Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1607734

[PATCH v5 1/4] syscalls: Restore address limit after a syscall

Path csiph.com!news.mixmin.net!aioe.org!bofh.it!news.nic.it!robomod
From Thomas Garnier <thgarnie@google.com>
Newsgroups linux.kernel
Subject [PATCH v5 1/4] syscalls: Restore address limit after a syscall
Date Thu, 23 Mar 2017 18:30:02 +0100
Message-ID <toeIF-5py-3@gated-at.bofh.it> (permalink)
X-Original-To Martin Schwidefsky <schwidefsky@de.ibm.com>, Heiko Carstens <heiko.carstens@de.ibm.com>, David Howells <dhowells@redhat.com>, Arnd Bergmann <arnd@arndb.de>, Dave Hansen <dave.hansen@intel.com>, Al Viro <viro@zeniv.linux.org.uk>, Thomas Gleixner <tglx@linutronix.de>, René Nyffenegger <mail@renenyffenegger.ch>, Thomas Garnier <thgarnie@google.com>, Andrew Morton <akpm@linux-foundation.org>, "Paul E . McKenney" <paulmck@linux.vnet.ibm.com>, Ingo Molnar <mingo@kernel.org>, Oleg Nesterov <oleg@redhat.com>, Pavel Tikhomirov <ptikhomirov@virtuozzo.com>, Stephen Smalley <sds@tycho.nsa.gov>, Ingo Molnar <mingo@redhat.com>, "H . Peter Anvin" <hpa@zytor.com>, Andy Lutomirski <luto@kernel.org>, Paolo Bonzini <pbonzini@redhat.com>, Rik van Riel <riel@redhat.com>, Kees Cook <keescook@chromium.org>, Josh Poimboeuf <jpoimboe@redhat.com>, Borislav Petkov <bp@alien8.de>, Brian Gerst <brgerst@gmail.com>, "Kirill A . Shutemov" <kirill.shutemov@linux.intel.com>, Christian Borntraeger <borntraeger@de.ibm.com>, Russell King <linux@armlinux.org.uk>, Will Deacon <will.deacon@arm.com>, Catalin Marinas <catalin.marinas@arm.com>, Mark Rutland <mark.rutland@arm.com>, James Morse <james.morse@arm.com>
Dkim-Signature v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=dNt4fxDRSCq//pZO1N1/pX1tzqm0md2OVPgfgYS+0VA=; b=a7oi2NLQTgZS759FFNBWaGxrogoLC/iuP9yaUcPzPQvALNEtdbbWgGOJadjbDQR5K3 AsPcpSYPW3tiEfQbWij9OEVwgqQT2IdeF1mcnBph3WSnYZ468Y4sozz1Y02MrLXk7cD6 deRI1KGGhxQ3Pw0qBDzhe8RVV4pEIS5I4+4642o8tfSmB3gVJo7iIa43V893U+uKO7Ni F8rMP/TIZp2kZW/ENOsJIpRk961ElG5pl68+Ih6mcQqDB/EsTvIP7U3wPtZuFZ1tG44n tq1hwn8P93fqjuMRLV15XMGv5J/E/lIUow7VM04mFPNSQ4VJ89m4kcRKO7J2NsVtX6aW MyRg==
X-Google-Dkim-Signature v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=dNt4fxDRSCq//pZO1N1/pX1tzqm0md2OVPgfgYS+0VA=; b=HaB0IwraYMzRSGIdhjd2511Y1O6QwTVLvEHruFfNuVZ/2YDypn4PPZgHUASIiaV4bV Yt9qzboPowNevmQGBlnUDMgd8U3WsDVFU99fHvbz7uaybjf74FF7NOKQUTQ7Yp+LGfhx /tHocDIR19e99bM1LazuzV8lc9A7K3ral3ILNPYL/Z9ArlSsDKjygAQXK3glJiA7EYfJ avFWlMXEqFjQMxq7Ju4qa/JIXBqmEiriVoUdFu5E6In1TfW6wtto430U77SvxkCO8dyr KKssuQL7xRRkOL21cPYGzQ746cwxsnZnrUH8HCzeOrzCiH7+Yy0TtTjbTm/2vmELR0D4 2Kkg==
X-Gm-Message-State AFeK/H0w03KlehtmJeQJUSbGkfpX63WYb6DdMjRmSoNOMSqZMrAeg/PnJKcKYF9u9Ng3i0bd
X-Received by 10.98.207.68 with SMTP id b65mr4308649pfg.12.1490289922794; Thu, 23 Mar 2017 10:25:22 -0700 (PDT)
X-Mailer git-send-email 2.12.1.500.gab5fba24ee-goog
Sender robomod@news.nic.it
List-ID <linux-kernel.vger.kernel.org>
X-Mailing-List linux-kernel@vger.kernel.org
Approved robomod@news.nic.it
Lines 112
Organization linux.* mail to news gateway
X-Original-Cc linux-s390@vger.kernel.org, linux-kernel@vger.kernel.org, linux-api@vger.kernel.org, x86@kernel.org, linux-arm-kernel@lists.infradead.org, kernel-hardening@lists.openwall.com
X-Original-Date Thu, 23 Mar 2017 10:25:12 -0700
X-Original-Message-ID <20170323172515.27950-1-thgarnie@google.com>
X-Original-Sender linux-kernel-owner@vger.kernel.org
Xref csiph.com linux.kernel:1607734

Show key headers only | View raw


This patch ensures a syscall does not return to user-mode with a kernel
address limit. If that happened, a process can corrupt kernel-mode
memory and elevate privileges.

For example, it would mitigation this bug:

- https://bugs.chromium.org/p/project-zero/issues/detail?id=990

The CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE option is also
added so each architecture can optimize this change.

Signed-off-by: Thomas Garnier <thgarnie@google.com>
---
Based on next-20170322
---
 arch/s390/Kconfig        |  1 +
 include/linux/syscalls.h | 26 +++++++++++++++++++++++++-
 init/Kconfig             |  7 +++++++
 kernel/sys.c             |  7 +++++++
 4 files changed, 40 insertions(+), 1 deletion(-)

diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index a2dcef0aacc7..b73f5b87bc99 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -103,6 +103,7 @@ config S390
 	select ARCH_INLINE_WRITE_UNLOCK_BH
 	select ARCH_INLINE_WRITE_UNLOCK_IRQ
 	select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+	select ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE
 	select ARCH_SAVE_PAGE_KEYS if HIBERNATION
 	select ARCH_SUPPORTS_ATOMIC_RMW
 	select ARCH_SUPPORTS_NUMA_BALANCING
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 980c3c9b06f8..f9ff80fa92ff 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -191,6 +191,27 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	SYSCALL_METADATA(sname, x, __VA_ARGS__)			\
 	__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
 
+
+/*
+ * Called before coming back to user-mode. Returning to user-mode with an
+ * address limit different than USER_DS can allow to overwrite kernel memory.
+ */
+static inline void verify_pre_usermode_state(void) {
+	BUG_ON(!segment_eq(get_fs(), USER_DS));
+}
+
+#ifndef CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE
+#define __CHECK_USER_CALLER() \
+	bool user_caller = segment_eq(get_fs(), USER_DS)
+#define __VERIFY_PRE_USERMODE_STATE() \
+	if (user_caller) verify_pre_usermode_state()
+#else
+#define __CHECK_USER_CALLER()
+#define __VERIFY_PRE_USERMODE_STATE()
+asmlinkage void asm_verify_pre_usermode_state(void);
+#endif
+
+
 #define __PROTECT(...) asmlinkage_protect(__VA_ARGS__)
 #define __SYSCALL_DEFINEx(x, name, ...)					\
 	asmlinkage long sys##name(__MAP(x,__SC_DECL,__VA_ARGS__))	\
@@ -199,7 +220,10 @@ extern struct trace_event_functions exit_syscall_print_funcs;
 	asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__));	\
 	asmlinkage long SyS##name(__MAP(x,__SC_LONG,__VA_ARGS__))	\
 	{								\
-		long ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__));	\
+		long ret;						\
+		__CHECK_USER_CALLER();					\
+		ret = SYSC##name(__MAP(x,__SC_CAST,__VA_ARGS__));	\
+		__VERIFY_PRE_USERMODE_STATE();				\
 		__MAP(x,__SC_TEST,__VA_ARGS__);				\
 		__PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__));	\
 		return ret;						\
diff --git a/init/Kconfig b/init/Kconfig
index c859c993c26f..c4efc3a95e4a 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1929,6 +1929,13 @@ config PROFILING
 config TRACEPOINTS
 	bool
 
+#
+# Set by each architecture that want to optimize how verify_pre_usermode_state
+# is called.
+#
+config ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE
+	bool
+
 source "arch/Kconfig"
 
 endmenu		# General setup
diff --git a/kernel/sys.c b/kernel/sys.c
index 196c7134bee6..4ae278fcc290 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -2459,3 +2459,10 @@ COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
 	return 0;
 }
 #endif /* CONFIG_COMPAT */
+
+#ifdef CONFIG_ARCH_NO_SYSCALL_VERIFY_PRE_USERMODE_STATE
+asmlinkage void asm_verify_pre_usermode_state(void)
+{
+	verify_pre_usermode_state();
+}
+#endif
-- 
2.12.1.500.gab5fba24ee-goog

Back to linux.kernel | Previous | NextNext in thread | Find similar | Unroll thread


Thread

[PATCH v5 1/4] syscalls: Restore address limit after a syscall Thomas Garnier <thgarnie@google.com> - 2017-03-23 18:30 +0100
  [PATCH v5 4/4] arm64/syscalls: Specific usage of verify_pre_usermode_state Thomas Garnier <thgarnie@google.com> - 2017-03-23 18:30 +0100
    Re: [PATCH v5 4/4] arm64/syscalls: Specific usage of verify_pre_usermode_state Thomas Garnier <thgarnie@google.com> - 2017-03-23 21:40 +0100
  Re: [PATCH v5 1/4] syscalls: Restore address limit after a syscall Kees Cook <keescook@chromium.org> - 2017-03-23 21:20 +0100

csiph-web