72 lines
2.4 KiB
Diff
72 lines
2.4 KiB
Diff
From 5ea0727b163cb5575e36397a12eade68a1f35f24 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Garnier <thgarnie@google.com>
|
|
Date: Wed, 14 Jun 2017 18:12:01 -0700
|
|
Subject: x86/syscalls: Check address limit on user-mode return
|
|
|
|
Ensure the address limit is a user-mode segment before returning to
|
|
user-mode. Otherwise a process can corrupt kernel-mode memory and elevate
|
|
privileges [1].
|
|
|
|
The set_fs function sets the TIF_SETFS flag to force a slow path on
|
|
return. In the slow path, the address limit is checked to be USER_DS if
|
|
needed.
|
|
|
|
The addr_limit_user_check function is added as a cross-architecture
|
|
function to check the address limit.
|
|
|
|
[1] https://bugs.chromium.org/p/project-zero/issues/detail?id=990
|
|
|
|
Signed-off-by: Thomas Garnier <thgarnie@google.com>
|
|
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Cc: Mark Rutland <mark.rutland@arm.com>
|
|
Cc: kernel-hardening@lists.openwall.com
|
|
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
|
Cc: Will Deacon <will.deacon@arm.com>
|
|
Cc: David Howells <dhowells@redhat.com>
|
|
Cc: Dave Hansen <dave.hansen@intel.com>
|
|
Cc: Miroslav Benes <mbenes@suse.cz>
|
|
Cc: Chris Metcalf <cmetcalf@mellanox.com>
|
|
Cc: Pratyush Anand <panand@redhat.com>
|
|
Cc: Russell King <linux@armlinux.org.uk>
|
|
Cc: Petr Mladek <pmladek@suse.com>
|
|
Cc: Rik van Riel <riel@redhat.com>
|
|
Cc: Kees Cook <keescook@chromium.org>
|
|
Cc: Arnd Bergmann <arnd@arndb.de>
|
|
Cc: Al Viro <viro@zeniv.linux.org.uk>
|
|
Cc: Andy Lutomirski <luto@kernel.org>
|
|
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
|
Cc: linux-arm-kernel@lists.infradead.org
|
|
Cc: Will Drewry <wad@chromium.org>
|
|
Cc: linux-api@vger.kernel.org
|
|
Cc: Oleg Nesterov <oleg@redhat.com>
|
|
Cc: Andy Lutomirski <luto@amacapital.net>
|
|
Cc: Paolo Bonzini <pbonzini@redhat.com>
|
|
Link: http://lkml.kernel.org/r/20170615011203.144108-1-thgarnie@google.com
|
|
---
|
|
arch/x86/include/asm/uaccess.h | 7 ++++++-
|
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
|
|
|
(limited to 'arch/x86/include/asm/uaccess.h')
|
|
|
|
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
|
|
index a059aac..11433f9 100644
|
|
--- a/arch/x86/include/asm/uaccess.h
|
|
+++ b/arch/x86/include/asm/uaccess.h
|
|
@@ -26,7 +26,12 @@
|
|
|
|
#define get_ds() (KERNEL_DS)
|
|
#define get_fs() (current->thread.addr_limit)
|
|
-#define set_fs(x) (current->thread.addr_limit = (x))
|
|
+static inline void set_fs(mm_segment_t fs)
|
|
+{
|
|
+ current->thread.addr_limit = fs;
|
|
+ /* On user-mode return, check fs is correct */
|
|
+ set_thread_flag(TIF_FSCHECK);
|
|
+}
|
|
|
|
#define segment_eq(a, b) ((a).seg == (b).seg)
|
|
|
|
--
|
|
cgit v1.1
|
|
|