]> rtime.felk.cvut.cz Git - hercules2020/nv-tegra/linux-4.4.git/commitdiff
android: fiq_debugger: restrict access to critical commands.
authorMark Salyzyn <salyzyn@google.com>
Tue, 20 Dec 2016 23:59:19 +0000 (15:59 -0800)
committermobile promotions <svcmobile_promotions@nvidia.com>
Tue, 16 May 2017 13:05:49 +0000 (06:05 -0700)
Sysrq must be enabled via /proc/sys/kernel/sysrq as a security
measure to enable various critical fiq debugger commands that
either leak information or can be used as a system attack.

Default disabled, this will leave the reboot, reset, irqs, sleep,
nosleep, console and ps commands.  Reboot and reset commands
will be restricted from taking any parameters.  We will also
switch to showing the limited command set in this mode.

Signed-off-by: Mark Salyzyn <salyzyn@google.com>
Bug 32402555
Change-Id: I3f74b1ff5e4971d619bcb37a911fed68fbb538d5
Reviewed-on: http://git-master/r/1475531
Tested-by: Sunny Li <sunnyl@nvidia.com>
Reviewed-by: Hayden Du <haydend@nvidia.com>
drivers/staging/android/fiq_debugger/fiq_debugger.c
drivers/tty/sysrq.c
include/linux/sysrq.h

index ae13ada3c447d917b86fdd7df48343057e1152d6..00c3e39220922cbb91a0bc68ab5260808d39209e 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/smp.h>
+#include <linux/sysrq.h>
 #include <linux/timer.h>
 #include <linux/tty.h>
 #include <linux/tty_flip.h>
@@ -403,7 +404,7 @@ static void fiq_debugger_work(struct work_struct *work)
                cmd += 6;
                while (*cmd == ' ')
                        cmd++;
-               if (cmd != '\0')
+               if ((cmd != '\0') && sysrq_on())
                        kernel_restart(cmd);
                else
                        kernel_restart(NULL);
@@ -433,29 +434,40 @@ static void fiq_debugger_irq_exec(struct fiq_debugger_state *state, char *cmd)
 static void fiq_debugger_help(struct fiq_debugger_state *state)
 {
        fiq_debugger_printf(&state->output,
-                               "FIQ Debugger commands:\n"
-                               " pc            PC status\n"
-                               " regs          Register dump\n"
-                               " allregs       Extended Register dump\n"
-                               " bt            Stack trace\n"
-                               " reboot [<c>]  Reboot with command <c>\n"
-                               " reset [<c>]   Hard reset with command <c>\n"
-                               " irqs          Interupt status\n"
-                               " kmsg          Kernel log\n"
-                               " version       Kernel version\n");
+            "FIQ Debugger commands:\n");
+    if (sysrq_on()) {
+        fiq_debugger_printf(&state->output,
+                " pc            PC status\n"
+                " regs          Register dump\n"
+                " allregs       Extended Register dump\n"
+                " bt            Stack trace\n");
+        fiq_debugger_printf(&state->output,
+                " reboot [<c>]  Reboot with command <c>\n"
+                " reset [<c>]   Hard reset with command <c>\n"
+                " irqs          Interrupt status\n"
+                " kmsg          Kernel log\n"
+                " version       Kernel version\n");
+        fiq_debugger_printf(&state->output,
+                " cpu           Current CPU\n"
+                " cpu <number>  Switch to CPU<number>\n"
+                " sysrq         sysrq options\n"
+                " sysrq <param> Execute sysrq with <param>\n");
+    } else {
+        fiq_debugger_printf(&state->output,
+                " reboot        Reboot\n"
+                " reset         Hard reset\n"
+                " irqs          Interrupt status\n");
+    }
        fiq_debugger_printf(&state->output,
-                               " sleep         Allow sleep while in FIQ\n"
-                               " nosleep       Disable sleep while in FIQ\n"
-                               " console       Switch terminal to console\n"
-                               " cpu           Current CPU\n"
-                               " cpu <number>  Switch to CPU<number>\n");
-       fiq_debugger_printf(&state->output,
-                               " ps            Process list\n"
-                               " sysrq         sysrq options\n"
-                               " sysrq <param> Execute sysrq with <param>\n");
+            " sleep         Allow sleep while in FIQ\n"
+            " nosleep       Disable sleep while in FIQ\n"
+            " console       Switch terminal to console\n"
+            " ps            Process list\n");
 #ifdef CONFIG_KGDB
-       fiq_debugger_printf(&state->output,
-                               " kgdb          Enter kernel debugger\n");
+    if (fiq_kgdb_enable) {
+        fiq_debugger_printf(&state->output,
+                " kgdb          Enter kernel debugger\n");
+    }
 #endif
 }
 
@@ -487,18 +499,23 @@ static bool fiq_debugger_fiq_exec(struct fiq_debugger_state *state,
        if (!strcmp(cmd, "help") || !strcmp(cmd, "?")) {
                fiq_debugger_help(state);
        } else if (!strcmp(cmd, "pc")) {
-               fiq_debugger_dump_pc(&state->output, regs);
+               if (sysrq_on())
+                       fiq_debugger_dump_pc(&state->output, regs);
        } else if (!strcmp(cmd, "regs")) {
-               fiq_debugger_dump_regs(&state->output, regs);
+               if (sysrq_on())
+                       fiq_debugger_dump_regs(&state->output, regs);
        } else if (!strcmp(cmd, "allregs")) {
-               fiq_debugger_dump_allregs(&state->output, regs);
+               if (sysrq_on())
+                       fiq_debugger_dump_allregs(&state->output, regs);
        } else if (!strcmp(cmd, "bt")) {
-               fiq_debugger_dump_stacktrace(&state->output, regs, 100, svc_sp);
+               if (sysrq_on())
+                       fiq_debugger_dump_stacktrace(&state->output, regs,
+                                                    100, svc_sp);
        } else if (!strncmp(cmd, "reset", 5)) {
                cmd += 5;
                while (*cmd == ' ')
                        cmd++;
-               if (*cmd) {
+               if (*cmd && sysrq_on()) {
                        char tmp_cmd[32];
                        strlcpy(tmp_cmd, cmd, sizeof(tmp_cmd));
                        machine_restart(tmp_cmd);
@@ -508,9 +525,12 @@ static bool fiq_debugger_fiq_exec(struct fiq_debugger_state *state,
        } else if (!strcmp(cmd, "irqs")) {
                fiq_debugger_dump_irqs(state);
        } else if (!strcmp(cmd, "kmsg")) {
-               fiq_debugger_dump_kernel_log(state);
+               if (sysrq_on())
+                       fiq_debugger_dump_kernel_log(state);
        } else if (!strcmp(cmd, "version")) {
-               fiq_debugger_printf(&state->output, "%s\n", linux_banner);
+               if (sysrq_on())
+                       fiq_debugger_printf(&state->output, "%s\n",
+                                           linux_banner);
        } else if (!strcmp(cmd, "sleep")) {
                state->no_sleep = false;
                fiq_debugger_printf(&state->output, "enabling sleep\n");
@@ -522,14 +542,17 @@ static bool fiq_debugger_fiq_exec(struct fiq_debugger_state *state,
                fiq_debugger_uart_flush(state);
                state->console_enable = true;
        } else if (!strcmp(cmd, "cpu")) {
-               fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
-       } else if (!strncmp(cmd, "cpu ", 4)) {
+        if (sysrq_on())
+            fiq_debugger_printf(&state->output, "cpu %d\n",
+                    state->current_cpu);
+       } else if (!strncmp(cmd, "cpu ", 4) && sysrq_on()) {
                unsigned long cpu = 0;
                if (kstrtoul(cmd + 4, 10, &cpu) == 0)
                        fiq_debugger_switch_cpu(state, cpu);
                else
                        fiq_debugger_printf(&state->output, "invalid cpu\n");
-               fiq_debugger_printf(&state->output, "cpu %d\n", state->current_cpu);
+               fiq_debugger_printf(&state->output, "cpu %d\n",
+                state->current_cpu);
        } else {
                if (state->debug_busy) {
                        fiq_debugger_printf(&state->output,
index 460ae1f9a0feacab50c4a6c95554eb580eccc6c8..8e5c6dde3f040028df8d319b57805298dc476050 100644 (file)
 static int __read_mostly sysrq_enabled = CONFIG_MAGIC_SYSRQ_DEFAULT_ENABLE;
 static bool __read_mostly sysrq_always_enabled;
 
-static bool sysrq_on(void)
+bool sysrq_on(void)
 {
        return sysrq_enabled || sysrq_always_enabled;
 }
+EXPORT_SYMBOL(sysrq_on);
 
 /*
  * A value of 1 means 'all', other nonzero values are an op mask:
index 387fa7d05c982b758942f83395e328949324fc1a..d802692acb539a7f21727eaf5c1dba45aa6f713c 100644 (file)
@@ -42,6 +42,7 @@ struct sysrq_key_op {
  * are available -- else NULL's).
  */
 
+bool sysrq_on(void);
 void handle_sysrq(int key);
 void __handle_sysrq(int key, bool check_mask);
 int register_sysrq_key(int key, struct sysrq_key_op *op);