From patchwork Fri Nov 23 00:53:56 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anton Vorontsov X-Patchwork-Id: 13104 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 4DF9C23E08 for ; Fri, 23 Nov 2012 00:57:44 +0000 (UTC) Received: from mail-ie0-f180.google.com (mail-ie0-f180.google.com [209.85.223.180]) by fiordland.canonical.com (Postfix) with ESMTP id 054FBA18BB3 for ; Fri, 23 Nov 2012 00:57:43 +0000 (UTC) Received: by mail-ie0-f180.google.com with SMTP id c10so1228520ieb.11 for ; Thu, 22 Nov 2012 16:57:43 -0800 (PST) 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=hG4JiqHih67uiKPiqj5WstguU4Derxc4wvXp6Hj/Oew=; b=RCPeE55npXi/Mgb2kJR4fGz8cUZ960BfZIFXrxwbmrANJiZ/LopScjWp2cN5CDj3TS 9UsdEcK5JOsQ5vlr0LFWc1jVL6hjZTTHi36jNuXDPCAwrCAw2cnRu5jhfBjrLF52cpyL 83aStzKHH9h3mTQiBxi6N0V2e4P+n89hSPAEFxWvpL9Ynj+n0KR2XX/ioCZmIRqznyRz IZrHcK0xzLmmKGFWtH9Hl1wRn2sf7ZLVgPu3x+9EhGn2PkT/x3pmimy23zPmvvjGaFiC WQFKAcimJ2bgzrmM5a3vp+fW6i+LuSrvsVFYxglK7TG6x0MqpryxL4HjSOnIs+6Btgei eD/Q== Received: by 10.50.213.34 with SMTP id np2mr2065877igc.57.1353632263799; Thu, 22 Nov 2012 16:57:43 -0800 (PST) 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.50.67.148 with SMTP id n20csp282702igt; Thu, 22 Nov 2012 16:57:43 -0800 (PST) Received: by 10.60.170.142 with SMTP id am14mr1692675oec.40.1353632262897; Thu, 22 Nov 2012 16:57:42 -0800 (PST) Received: from mail-oa0-f46.google.com (mail-oa0-f46.google.com [209.85.219.46]) by mx.google.com with ESMTPS id k6si4248424obd.193.2012.11.22.16.57.42 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 22 Nov 2012 16:57:42 -0800 (PST) Received-SPF: neutral (google.com: 209.85.219.46 is neither permitted nor denied by best guess record for domain of anton.vorontsov@linaro.org) client-ip=209.85.219.46; Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.219.46 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-oa0-f46.google.com with SMTP id h16so10032048oag.5 for ; Thu, 22 Nov 2012 16:57:42 -0800 (PST) Received: by 10.60.1.164 with SMTP id 4mr1636575oen.47.1353632262617; Thu, 22 Nov 2012 16:57:42 -0800 (PST) Received: from localhost (ip-64-134-239-153.public.wayport.net. [64.134.239.153]) by mx.google.com with ESMTPS id b20sm4483863obu.4.2012.11.22.16.57.39 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 22 Nov 2012 16:57:42 -0800 (PST) From: Anton Vorontsov To: Andrew Morton Cc: Jason Wessel , John Stultz , linux-kernel@vger.kernel.org, linaro-kernel@lists.linaro.org, patches@linaro.org, kernel-team@android.com, kgdb-bugreport@lists.sourceforge.net Subject: [PATCH 7/7] kdb: Add kiosk mode Date: Thu, 22 Nov 2012 16:53:56 -0800 Message-Id: <1353632036-5354-7-git-send-email-anton.vorontsov@linaro.org> X-Mailer: git-send-email 1.8.0 In-Reply-To: <20121123005315.GA12690@lizard.mcd25758.sjc.wayport.net> References: <20121123005315.GA12690@lizard.mcd25758.sjc.wayport.net> X-Gm-Message-State: ALoCoQkVwn/N+mlX+3ARPq+6BpexdsVbhmFsUB31kPGz7xDbU0yNiT1JnPIcOi/vt8hIFBQNIXkd By issuing 'echo 1 > /sys/module/kdb/parameters/kiosk' or booting with kdb.kiosk=1 kernel command line option, one can still have a somewhat usable debugging facility, but not fearing that the debugger can be used to easily gain root access or dump sensitive data. Without the kiosk mode, obtaining the root rights via KDB is a matter of a few commands, and works everywhere. For example, log in as a normal user: cbou:~$ id uid=1001(cbou) gid=1001(cbou) groups=1001(cbou) Now enter KDB (for example via sysrq): Entering kdb (current=0xffff8800065bc740, pid 920) due to Keyboard Entry kdb> ps 23 sleeping system daemon (state M) processes suppressed, use 'ps A' to see all. Task Addr Pid Parent [*] cpu State Thread Command 0xffff8800065bc740 920 919 1 0 R 0xffff8800065bca20 *bash 0xffff880007078000 1 0 0 0 S 0xffff8800070782e0 init [...snip...] 0xffff8800065be3c0 918 1 0 0 S 0xffff8800065be6a0 getty 0xffff8800065b9c80 919 1 0 0 S 0xffff8800065b9f60 login 0xffff8800065bc740 920 919 1 0 R 0xffff8800065bca20 *bash All we need is the offset of cred pointers. We can look up the offset in the distro's kernel source, but it is unnecessary. We can just start dumping init's task_struct, until we see the process name: kdb> md 0xffff880007078000 0xffff880007078000 0000000000000001 ffff88000703c000 ................ 0xffff880007078010 0040210000000002 0000000000000000 .....!@......... [...snip...] 0xffff8800070782b0 ffff8800073e0580 ffff8800073e0580 ..>.......>..... 0xffff8800070782c0 0000000074696e69 0000000000000000 init............ ^ Here, 'init'. Creds are just above it, so the offset is 0x02b0. Now we set up init's creds for our non-privileged shell: kdb> mm 0xffff8800065bc740+0x02b0 0xffff8800073e0580 0xffff8800065bc9f0 = 0xffff8800073e0580 kdb> mm 0xffff8800065bc740+0x02b8 0xffff8800073e0580 0xffff8800065bc9f8 = 0xffff8800073e0580 And thus gaining the root: kdb> go cbou:~$ id uid=0(root) gid=0(root) groups=0(root) cbou:~$ bash root:~# p.s. No distro enables kdb by default (although, with a nice KDB-over-KMS feature availability, I would expect at least some would enable it), so it's not actually some kind of a major issue. Signed-off-by: Anton Vorontsov --- include/linux/kdb.h | 1 + kernel/debug/kdb/kdb_main.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/include/linux/kdb.h b/include/linux/kdb.h index abe927c..3a2c554 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h @@ -63,6 +63,7 @@ extern atomic_t kdb_event; #define KDB_BADLENGTH (-19) #define KDB_NOBP (-20) #define KDB_BADADDR (-21) +#define KDB_NOPERM (-22) /* * kdb_diemsg diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 83c3f60..36e4c2a 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -12,6 +12,7 @@ */ #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -42,6 +44,12 @@ #include #include "kdb_private.h" +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "kdb." + +static bool kdb_kiosk; +module_param_named(kiosk, kdb_kiosk, bool, 0600); + #define GREP_LEN 256 char kdb_grep_string[GREP_LEN]; int kdb_grepping_flag; @@ -121,6 +129,7 @@ static kdbmsg_t kdbmsgs[] = { KDBMSG(BADLENGTH, "Invalid length field"), KDBMSG(NOBP, "No Breakpoint exists"), KDBMSG(BADADDR, "Invalid address"), + KDBMSG(NOPERM, "Permission denied"), }; #undef KDBMSG @@ -987,6 +996,14 @@ int kdb_parse(const char *cmdstr) if (i < kdb_max_commands) { int result; + + if (kdb_kiosk) { + if (!(tp->cmd_flags & (KDB_SAFE | KDB_SAFE_NO_ARGS))) + return KDB_NOPERM; + if (tp->cmd_flags & KDB_SAFE_NO_ARGS && argc > 1) + return KDB_NOPERM; + } + KDB_STATE_SET(CMD); result = (*tp->cmd_func)(argc-1, (const char **)argv); if (result && ignore_errors && result > KDB_CMD_GO) @@ -1009,7 +1026,7 @@ int kdb_parse(const char *cmdstr) * obtaining the address of a variable, or the nearest symbol * to an address contained in a register. */ - { + if (!kdb_kiosk) { unsigned long value; char *name = NULL; long offset; @@ -1025,6 +1042,7 @@ int kdb_parse(const char *cmdstr) kdb_printf("\n"); return 0; } + return KDB_NOPERM; }