]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - releases/4.4.177/x86-uaccess-don-t-leak-the-ac-flag-into-__put_user-value-evaluation.patch
Linux 4.4.177
[thirdparty/kernel/stable-queue.git] / releases / 4.4.177 / x86-uaccess-don-t-leak-the-ac-flag-into-__put_user-value-evaluation.patch
1 From 2a418cf3f5f1caf911af288e978d61c9844b0695 Mon Sep 17 00:00:00 2001
2 From: Andy Lutomirski <luto@kernel.org>
3 Date: Fri, 22 Feb 2019 17:17:04 -0800
4 Subject: x86/uaccess: Don't leak the AC flag into __put_user() value evaluation
5
6 From: Andy Lutomirski <luto@kernel.org>
7
8 commit 2a418cf3f5f1caf911af288e978d61c9844b0695 upstream.
9
10 When calling __put_user(foo(), ptr), the __put_user() macro would call
11 foo() in between __uaccess_begin() and __uaccess_end(). If that code
12 were buggy, then those bugs would be run without SMAP protection.
13
14 Fortunately, there seem to be few instances of the problem in the
15 kernel. Nevertheless, __put_user() should be fixed to avoid doing this.
16 Therefore, evaluate __put_user()'s argument before setting AC.
17
18 This issue was noticed when an objtool hack by Peter Zijlstra complained
19 about genregs_get() and I compared the assembly output to the C source.
20
21 [ bp: Massage commit message and fixed up whitespace. ]
22
23 Fixes: 11f1a4b9755f ("x86: reorganize SMAP handling in user space accesses")
24 Signed-off-by: Andy Lutomirski <luto@kernel.org>
25 Signed-off-by: Borislav Petkov <bp@suse.de>
26 Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
27 Cc: Peter Zijlstra <peterz@infradead.org>
28 Cc: Brian Gerst <brgerst@gmail.com>
29 Cc: Josh Poimboeuf <jpoimboe@redhat.com>
30 Cc: Denys Vlasenko <dvlasenk@redhat.com>
31 Cc: stable@vger.kernel.org
32 Link: http://lkml.kernel.org/r/20190225125231.845656645@infradead.org
33 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
34
35 ---
36 arch/x86/include/asm/uaccess.h | 7 ++++---
37 1 file changed, 4 insertions(+), 3 deletions(-)
38
39 --- a/arch/x86/include/asm/uaccess.h
40 +++ b/arch/x86/include/asm/uaccess.h
41 @@ -314,8 +314,7 @@ do { \
42 __put_user_asm(x, ptr, retval, "l", "k", "ir", errret); \
43 break; \
44 case 8: \
45 - __put_user_asm_u64((__typeof__(*ptr))(x), ptr, retval, \
46 - errret); \
47 + __put_user_asm_u64(x, ptr, retval, errret); \
48 break; \
49 default: \
50 __put_user_bad(); \
51 @@ -426,8 +425,10 @@ do { \
52 #define __put_user_nocheck(x, ptr, size) \
53 ({ \
54 int __pu_err; \
55 + __typeof__(*(ptr)) __pu_val; \
56 + __pu_val = x; \
57 __uaccess_begin(); \
58 - __put_user_size((x), (ptr), (size), __pu_err, -EFAULT); \
59 + __put_user_size(__pu_val, (ptr), (size), __pu_err, -EFAULT);\
60 __uaccess_end(); \
61 __builtin_expect(__pu_err, 0); \
62 })