From: Jan Kara Allow admin to enable only some of the Magic-Sysrq functions. This allows admin to disable sysrq functions he considers dangerous (e.g. sending kill signal, remounting fs RO) while keeping the possibility to use the others (e.g. debug deadlocks by dumps of processes etc.). Signed-off-by: Jan Kara Signed-off-by: Andrew Morton --- 25-akpm/Documentation/sysrq.txt | 27 +++++++++++++++++++++------ 25-akpm/drivers/char/sysrq.c | 24 ++++++++++++++++++++---- 25-akpm/include/linux/sysrq.h | 12 ++++++++++++ 25-akpm/kernel/power/poweroff.c | 3 ++- 4 files changed, 55 insertions(+), 11 deletions(-) diff -puN Documentation/sysrq.txt~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions Documentation/sysrq.txt --- 25/Documentation/sysrq.txt~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions Fri Nov 12 15:57:26 2004 +++ 25-akpm/Documentation/sysrq.txt Fri Nov 12 15:57:26 2004 @@ -10,13 +10,28 @@ regardless of whatever else it is doing, * How do I enable the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ You need to say "yes" to 'Magic SysRq key (CONFIG_MAGIC_SYSRQ)' when -configuring the kernel. When running on a kernel with SysRq compiled in, it -may be DISABLED at run-time using following command: +configuring the kernel. When running a kernel with SysRq compiled in, +/proc/sys/kernel/sysrq controls the functions allowed to be invoked via +the SysRq key. By default the file contains 1 which means that every +possible SysRq request is allowed (in older versions SysRq was disabled +by default, and you were required to specifically enable it at run-time +but this is not the case any more). Here is the list of possible values +in /proc/sys/kernel/sysrq: + 0 - disable sysrq completely + 1 - enable all functions of sysrq + >1 - bitmask of allowed sysrq functions (see below for detailed function + description): + 2 - enable control of console logging level + 4 - enable control of keyboard (SAK, unraw) + 8 - enable debugging dumps of processes etc. + 16 - enable sync command + 32 - enable remount read-only + 64 - enable signalling of processes (term, kill, oom-kill) + 128 - allow reboot/poweroff + 256 - allow nicing of all RT tasks - echo "0" > /proc/sys/kernel/sysrq - -Note that previous versions disabled sysrq by default, and you were required -to specifically enable it at run-time. That is not the case any longer. +You can set the value in the file by the following command: + echo "number" >/proc/sys/kernel/sysrq * How do I use the magic SysRq key? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff -puN drivers/char/sysrq.c~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions drivers/char/sysrq.c --- 25/drivers/char/sysrq.c~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions Fri Nov 12 15:57:26 2004 +++ 25-akpm/drivers/char/sysrq.c Fri Nov 12 15:57:26 2004 @@ -58,6 +58,7 @@ static struct sysrq_key_op sysrq_logleve .handler = sysrq_handle_loglevel, .help_msg = "loglevel0-8", .action_msg = "Changing Loglevel", + .enable_mask = SYSRQ_ENABLE_LOG, }; @@ -74,6 +75,7 @@ static struct sysrq_key_op sysrq_SAK_op .handler = sysrq_handle_SAK, .help_msg = "saK", .action_msg = "SAK", + .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #endif @@ -91,6 +93,7 @@ static struct sysrq_key_op sysrq_unraw_o .handler = sysrq_handle_unraw, .help_msg = "unRaw", .action_msg = "Keyboard mode set to XLATE", + .enable_mask = SYSRQ_ENABLE_KEYBOARD, }; #endif /* CONFIG_VT */ @@ -105,6 +108,7 @@ static struct sysrq_key_op sysrq_reboot_ .handler = sysrq_handle_reboot, .help_msg = "reBoot", .action_msg = "Resetting", + .enable_mask = SYSRQ_ENABLE_BOOT, }; static void sysrq_handle_sync(int key, struct pt_regs *pt_regs, @@ -117,6 +121,7 @@ static struct sysrq_key_op sysrq_sync_op .handler = sysrq_handle_sync, .help_msg = "Sync", .action_msg = "Emergency Sync", + .enable_mask = SYSRQ_ENABLE_SYNC, }; static void sysrq_handle_mountro(int key, struct pt_regs *pt_regs, @@ -129,6 +134,7 @@ static struct sysrq_key_op sysrq_mountro .handler = sysrq_handle_mountro, .help_msg = "Unmount", .action_msg = "Emergency Remount R/O", + .enable_mask = SYSRQ_ENABLE_REMOUNT, }; /* END SYNC SYSRQ HANDLERS BLOCK */ @@ -146,6 +152,7 @@ static struct sysrq_key_op sysrq_showreg .handler = sysrq_handle_showregs, .help_msg = "showPc", .action_msg = "Show Regs", + .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -158,6 +165,7 @@ static struct sysrq_key_op sysrq_showsta .handler = sysrq_handle_showstate, .help_msg = "showTasks", .action_msg = "Show State", + .enable_mask = SYSRQ_ENABLE_DUMP, }; @@ -170,6 +178,7 @@ static struct sysrq_key_op sysrq_showmem .handler = sysrq_handle_showmem, .help_msg = "showMem", .action_msg = "Show Memory", + .enable_mask = SYSRQ_ENABLE_DUMP, }; /* SHOW SYSRQ HANDLERS BLOCK */ @@ -200,6 +209,7 @@ static struct sysrq_key_op sysrq_term_op .handler = sysrq_handle_term, .help_msg = "tErm", .action_msg = "Terminate All Tasks", + .enable_mask = SYSRQ_ENABLE_SIGNAL, }; static void sysrq_handle_moom(int key, struct pt_regs *pt_regs, @@ -224,6 +234,7 @@ static struct sysrq_key_op sysrq_kill_op .handler = sysrq_handle_kill, .help_msg = "kIll", .action_msg = "Kill All Tasks", + .enable_mask = SYSRQ_ENABLE_SIGNAL, }; /* END SIGNAL SYSRQ HANDLERS BLOCK */ @@ -236,7 +247,8 @@ static void sysrq_handle_unrt(int key, s static struct sysrq_key_op sysrq_unrt_op = { .handler = sysrq_handle_unrt, .help_msg = "Nice", - .action_msg = "Nice All RT Tasks" + .action_msg = "Nice All RT Tasks", + .enable_mask = SYSRQ_ENABLE_RTNICE, }; /* Key Operations table and lock */ @@ -346,9 +358,13 @@ void __handle_sysrq(int key, struct pt_r op_p = __sysrq_get_key_op(key); if (op_p) { - printk ("%s\n", op_p->action_msg); - console_loglevel = orig_log_level; - op_p->handler(key, pt_regs, tty); + if (sysrq_enabled == 1 || sysrq_enabled & op_p->enable_mask) { + printk ("%s\n", op_p->action_msg); + console_loglevel = orig_log_level; + op_p->handler(key, pt_regs, tty); + } + else + printk("This sysrq operation is disabled.\n"); } else { printk("HELP : "); /* Only print the help msg once per handler */ diff -puN include/linux/sysrq.h~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions include/linux/sysrq.h --- 25/include/linux/sysrq.h~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions Fri Nov 12 15:57:26 2004 +++ 25-akpm/include/linux/sysrq.h Fri Nov 12 15:57:26 2004 @@ -16,10 +16,22 @@ struct pt_regs; struct tty_struct; +/* Possible values of bitmask for enabling sysrq functions */ +/* 0x0001 is reserved for enable everything */ +#define SYSRQ_ENABLE_LOG 0x0002 +#define SYSRQ_ENABLE_KEYBOARD 0x0004 +#define SYSRQ_ENABLE_DUMP 0x0008 +#define SYSRQ_ENABLE_SYNC 0x0010 +#define SYSRQ_ENABLE_REMOUNT 0x0020 +#define SYSRQ_ENABLE_SIGNAL 0x0040 +#define SYSRQ_ENABLE_BOOT 0x0080 +#define SYSRQ_ENABLE_RTNICE 0x0100 + struct sysrq_key_op { void (*handler)(int, struct pt_regs *, struct tty_struct *); char *help_msg; char *action_msg; + int enable_mask; }; #ifdef CONFIG_MAGIC_SYSRQ diff -puN kernel/power/poweroff.c~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions kernel/power/poweroff.c --- 25/kernel/power/poweroff.c~allow-admin-to-enable-only-some-of-the-magic-sysrq-functions Fri Nov 12 15:57:26 2004 +++ 25-akpm/kernel/power/poweroff.c Fri Nov 12 15:57:26 2004 @@ -32,7 +32,8 @@ static void handle_poweroff(int key, str static struct sysrq_key_op sysrq_poweroff_op = { .handler = handle_poweroff, .help_msg = "powerOff", - .action_msg = "Power Off" + .action_msg = "Power Off", + .enable_mask = SYSRQ_ENABLE_BOOT, }; static int pm_sysrq_init(void) _