aboutsummaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorThomas Garnier <[email protected]>2017-06-14 18:12:01 -0700
committerThomas Gleixner <[email protected]>2017-07-08 14:05:32 +0200
commit5ea0727b163cb5575e36397a12eade68a1f35f24 (patch)
tree20ce2b7ad1174b0ef87df07c1105bfb0fdd4788c /include/linux
parent4422d80ed7d4bdb2d6e9fb890c66c3d9250ba694 (diff)
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 <[email protected]> Signed-off-by: Thomas Gleixner <[email protected]> Cc: Mark Rutland <[email protected]> Cc: [email protected] Cc: Catalin Marinas <[email protected]> Cc: Will Deacon <[email protected]> Cc: David Howells <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Miroslav Benes <[email protected]> Cc: Chris Metcalf <[email protected]> Cc: Pratyush Anand <[email protected]> Cc: Russell King <[email protected]> Cc: Petr Mladek <[email protected]> Cc: Rik van Riel <[email protected]> Cc: Kees Cook <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Al Viro <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: [email protected] Cc: Will Drewry <[email protected]> Cc: [email protected] Cc: Oleg Nesterov <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Paolo Bonzini <[email protected]> Link: http://lkml.kernel.org/r/[email protected]
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/syscalls.h16
1 files changed, 16 insertions, 0 deletions
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index 980c3c9b06f8..ac0cf6fb25d6 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -206,6 +206,22 @@ extern struct trace_event_functions exit_syscall_print_funcs;
} \
static inline long SYSC##name(__MAP(x,__SC_DECL,__VA_ARGS__))
+#ifdef TIF_FSCHECK
+/*
+ * 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 addr_limit_user_check(void)
+{
+
+ if (!test_thread_flag(TIF_FSCHECK))
+ return;
+
+ BUG_ON(!segment_eq(get_fs(), USER_DS));
+ clear_thread_flag(TIF_FSCHECK);
+}
+#endif
+
asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
qid_t id, void __user *addr);
asmlinkage long sys_time(time_t __user *tloc);