From patchwork Thu Jul 26 14:26:30 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Vorontsov X-Patchwork-Id: 10274 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id A733223E57 for ; Thu, 26 Jul 2012 14:28:59 +0000 (UTC) Received: from mail-yx0-f180.google.com (mail-yx0-f180.google.com [209.85.213.180]) by fiordland.canonical.com (Postfix) with ESMTP id 613EBA18F37 for ; Thu, 26 Jul 2012 14:28:59 +0000 (UTC) Received: by yenq6 with SMTP id q6so2019999yen.11 for ; Thu, 26 Jul 2012 07:28:58 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:from:to:cc :subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=Mu1dmN7vH7GH1xWwALQETz+tedFUjYo673ZcAUuUAgc=; b=jZh8pvSgn+/O45LRZVEZ9xI0lyuW9Xk/U3z5vesmlP38moflh+M5jEPg/5Cer5/zSD 81v/HQsdCzohHdKKTHehKy9Dxo92HrmBWrbClGTFtWyxfOUJAcQ95IIGFXhKIjOyNOXx QGkXU6knwGzjuTVHWcTVL26mO6wZHea5ivzaetDlzAPzcY19vslV+SZWUaPSxiIzxS2o ern2+CHouyWHisVftOsfyZnoYJ4OKIpaH0VZQV1pskA2San6rBv0+a3f39E8cYitU8Uf E5Gxd665C2J2p90UTYAyqykWbNpn5XVNIObbMhgNCpY9t1MiGinSDHk4VoB/x6Uq4Y+e dM+w== Received: by 10.50.159.135 with SMTP id xc7mr1798843igb.1.1343312938410; Thu, 26 Jul 2012 07:28:58 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.43.93.3 with SMTP id bs3csp142669icc; Thu, 26 Jul 2012 07:28:57 -0700 (PDT) Received: by 10.66.78.9 with SMTP id x9mr20946693paw.84.1343312937498; Thu, 26 Jul 2012 07:28:57 -0700 (PDT) Received: from mail-pb0-f50.google.com (mail-pb0-f50.google.com [209.85.160.50]) by mx.google.com with ESMTPS id os3si39808282pbb.293.2012.07.26.07.28.57 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 26 Jul 2012 07:28:57 -0700 (PDT) Received-SPF: neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) client-ip=209.85.160.50; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.160.50 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) smtp.mail=anton.vorontsov@linaro.org Received: by mail-pb0-f50.google.com with SMTP id rr4so3773050pbb.37 for ; Thu, 26 Jul 2012 07:28:57 -0700 (PDT) Received: by 10.68.232.229 with SMTP id tr5mr5531014pbc.101.1343312937147; Thu, 26 Jul 2012 07:28:57 -0700 (PDT) Received: from localhost (c-71-204-165-222.hsd1.ca.comcast.net. [71.204.165.222]) by mx.google.com with ESMTPS id qd10sm16645886pbb.38.2012.07.26.07.28.55 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 26 Jul 2012 07:28:56 -0700 (PDT) From: Anton Vorontsov To: Jason Wessel Cc: Andrew Morton , Steven Rostedt , John Stultz , arve@android.com, linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org, patches@linaro.org, kernel-team@android.com, kgdb-bugreport@lists.sourceforge.net Subject: [PATCH 6/7] kdb: Mark safe commands as KDB_SAFE and KDB_SAFE_NO_ARGS Date: Thu, 26 Jul 2012 07:26:30 -0700 Message-Id: <1343312791-9138-6-git-send-email-anton.vorontsov@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <20120726142514.GA32158@lizard> References: <20120726142514.GA32158@lizard> X-Gm-Message-State: ALoCoQkKVUaNEQiG9NVT4Nb7KaGo+lX7JIEoPSOqe5e04DL5xfbHncUZ34r5qQE8f02ZQpjxZJyr This patch introduces two new flags: KDB_SAFE, denotes a safe command, and KDB_SAFE_NO_ARGS, denotes a safe command when used without arguments. The word "safe" here used in the sense that the commands cannot be used to leak sensitive data from the memory, and cannot be used to change program flow in a predefined manner. These flags will be used by the "kiosk" mode, i.e. when it is possible for the ordinary user to enter the KDB (or user can get the access to KDB after the crash), but we do not allow user to read dump the memory [and thus read some sensitive data]. The following commands were marked as "safe": Clear Breakpoint Enable Breakpoint Disable Breakpoint Display exception frame Stack traceback Display stack for process Display stack all processes Backtrace current process on each cpu Execute cmd for each element in linked list Show environment variables Set environment variables Display Help Message Switch to new cpu Display active task list Switch to another task Reboot the machine immediately List loaded kernel modules Magic SysRq key Display syslog buffer Define a set of commands, down to endefcmd Send a signal to a process Summarize the system The following commands were marked as safe when issued with no arguments: Continue Execution And the following commands are unsafe: Continue Execution (with address argument) Display Memory Contents Display Raw Memory Display Physical Memory Display Memory Symbolically Modify Memory Contents Display Registers Modify Registers Backtrace process given its struct task address Enter kgdb mode Display per_cpu variables Note that we mark "display registers" command unsafe, this is because single stepping + constantly dumping registers in string or memory functions can be used as a way to read sensitive data (it's actually trivial to exploit). Later we can do a bit better, i.e. not displaying general-purpose registers, but printing control registers. Signed-off-by: Anton Vorontsov --- include/linux/kdb.h | 2 ++ kernel/debug/kdb/kdb_bp.c | 17 +++++++++-------- kernel/debug/kdb/kdb_main.c | 44 +++++++++++++++++++++---------------------- kernel/trace/trace_kdb.c | 2 +- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/include/linux/kdb.h b/include/linux/kdb.h index d39d41d..36f6d09 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -35,6 +35,8 @@ extern atomic_t kdb_event; typedef enum { KDB_REPEAT_NO_ARGS = 0x1, /* Repeat the command w/o arguments */ KDB_REPEAT_WITH_ARGS = 0x2, /* Repeat the command w/ its arguments */ + KDB_SAFE = 0x4, /* Security-wise safe command */ + KDB_SAFE_NO_ARGS = 0x8, /* Only safe if run w/o arguments */ } kdb_cmdflags_t; typedef int (*kdb_func_t)(int, const char **); diff --git a/kernel/debug/kdb/kdb_bp.c b/kernel/debug/kdb/kdb_bp.c index 928e9e9..b95ddf7 100644 --- a/kernel/debug/kdb/kdb_bp.c +++ b/kernel/debug/kdb/kdb_bp.c @@ -546,23 +546,24 @@ void __init kdb_initbptab(void) bp->bp_free = 1; kdb_register_flags("bp", kdb_bp, "[]", - "Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS); + "Set/Display breakpoints", 0, KDB_REPEAT_NO_ARGS | KDB_SAFE); kdb_register_flags("bl", kdb_bp, "[]", - "Display breakpoints", 0, KDB_REPEAT_NO_ARGS); + "Display breakpoints", 0, KDB_REPEAT_NO_ARGS | KDB_SAFE); if (arch_kgdb_ops.flags & KGDB_HW_BREAKPOINT) kdb_register_flags("bph", kdb_bp, "[]", - "[datar [length]|dataw [length]] Set hw brk", 0, KDB_REPEAT_NO_ARGS); + "[datar [length]|dataw [length]] Set hw brk", 0, + KDB_REPEAT_NO_ARGS | KDB_SAFE); kdb_register_flags("bc", kdb_bc, "", - "Clear Breakpoint", 0, 0); + "Clear Breakpoint", 0, KDB_SAFE); kdb_register_flags("be", kdb_bc, "", - "Enable Breakpoint", 0, 0); + "Enable Breakpoint", 0, KDB_SAFE); kdb_register_flags("bd", kdb_bc, "", - "Disable Breakpoint", 0, 0); + "Disable Breakpoint", 0, KDB_SAFE); kdb_register_flags("ss", kdb_ss, "", - "Single Step", 1, KDB_REPEAT_NO_ARGS); + "Single Step", 1, KDB_REPEAT_NO_ARGS | KDB_SAFE); kdb_register_flags("ssb", kdb_ss, "", - "Single step to branch/call", 0, KDB_REPEAT_NO_ARGS); + "Single step to branch/call", 0, KDB_REPEAT_NO_ARGS | KDB_SAFE); /* * Architecture dependent initialization. */ diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 21e58fb..1bb18e6 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -2830,66 +2830,66 @@ static void __init kdb_inittab(void) kdb_register_flags("mm", kdb_mm, " ", "Modify Memory Contents", 0, KDB_REPEAT_NO_ARGS); kdb_register_flags("go", kdb_go, "[]", - "Continue Execution", 1, 0); + "Continue Execution", 1, KDB_SAFE_NO_ARGS); kdb_register_flags("rd", kdb_rd, "", "Display Registers", 0, 0); kdb_register_flags("rm", kdb_rm, " ", "Modify Registers", 0, 0); kdb_register_flags("ef", kdb_ef, "", - "Display exception frame", 0, 0); + "Display exception frame", 0, KDB_SAFE); kdb_register_flags("bt", kdb_bt, "[]", - "Stack traceback", 1, 0); + "Stack traceback", 1, KDB_SAFE); kdb_register_flags("btp", kdb_bt, "", - "Display stack for process ", 0, 0); + "Display stack for process ", 0, KDB_SAFE); kdb_register_flags("bta", kdb_bt, "[DRSTCZEUIMA]", - "Display stack all processes", 0, 0); + "Display stack all processes", 0, KDB_SAFE); kdb_register_flags("btc", kdb_bt, "", - "Backtrace current process on each cpu", 0, 0); + "Backtrace current process on each cpu", 0, KDB_SAFE); kdb_register_flags("btt", kdb_bt, "", "Backtrace process given its struct task address", 0, 0); kdb_register_flags("ll", kdb_ll, " ", - "Execute cmd for each element in linked list", 0, 0); + "Execute cmd for each element in linked list", 0, KDB_SAFE); kdb_register_flags("env", kdb_env, "", - "Show environment variables", 0, 0); + "Show environment variables", 0, KDB_SAFE); kdb_register_flags("set", kdb_set, "", - "Set environment variables", 0, 0); + "Set environment variables", 0, KDB_SAFE); kdb_register_flags("help", kdb_help, "", - "Display Help Message", 1, 0); + "Display Help Message", 1, KDB_SAFE); kdb_register_flags("?", kdb_help, "", - "Display Help Message", 0, 0); + "Display Help Message", 0, KDB_SAFE); kdb_register_flags("cpu", kdb_cpu, "", - "Switch to new cpu", 0, 0); + "Switch to new cpu", 0, KDB_SAFE); kdb_register_flags("kgdb", kdb_kgdb, "", "Enter kgdb mode", 0, 0); kdb_register_flags("ps", kdb_ps, "[|A]", - "Display active task list", 0, 0); + "Display active task list", 0, KDB_SAFE); kdb_register_flags("pid", kdb_pid, "", - "Switch to another task", 0, 0); + "Switch to another task", 0, KDB_SAFE); kdb_register_flags("reboot", kdb_reboot, "", - "Reboot the machine immediately", 0, 0); + "Reboot the machine immediately", 0, KDB_SAFE); #if defined(CONFIG_MODULES) kdb_register_flags("lsmod", kdb_lsmod, "", - "List loaded kernel modules", 0, 0); + "List loaded kernel modules", 0, KDB_SAFE); #endif #if defined(CONFIG_MAGIC_SYSRQ) kdb_register_flags("sr", kdb_sr, "", - "Magic SysRq key", 0, 0); + "Magic SysRq key", 0, KDB_SAFE); #endif #if defined(CONFIG_PRINTK) kdb_register_flags("dmesg", kdb_dmesg, "[lines]", - "Display syslog buffer", 0, 0); + "Display syslog buffer", 0, KDB_SAFE); #endif kdb_register_flags("defcmd", kdb_defcmd, "name \"usage\" \"help\"", - "Define a set of commands, down to endefcmd", 0, 0); + "Define a set of commands, down to endefcmd", 0, KDB_SAFE); kdb_register_flags("kill", kdb_kill, "<-signal> ", - "Send a signal to a process", 0, 0); + "Send a signal to a process", 0, KDB_SAFE); kdb_register_flags("summary", kdb_summary, "", - "Summarize the system", 4, 0); + "Summarize the system", 4, KDB_SAFE); kdb_register_flags("per_cpu", kdb_per_cpu, " [] []", "Display per_cpu variables", 3, 0); kdb_register_flags("grephelp", kdb_grep_help, "", - "Display help on | grep", 0, 0); + "Display help on | grep", 0, KDB_SAFE); } /* Execute any commands defined in kdb_cmds. */ diff --git a/kernel/trace/trace_kdb.c b/kernel/trace/trace_kdb.c index 1b68177..8353852 100644 --- a/kernel/trace/trace_kdb.c +++ b/kernel/trace/trace_kdb.c @@ -128,7 +128,7 @@ static int kdb_ftdump(int argc, const char **argv) static __init int kdb_ftrace_register(void) { kdb_register_flags("ftdump", kdb_ftdump, "[skip_#lines] [cpu]", - "Dump ftrace log", 0, 0); + "Dump ftrace log", 0, KDB_SAFE); return 0; }