diff options
author | Will Deacon <will.deacon@arm.com> | 2018-02-05 10:34:24 -0500 |
---|---|---|
committer | Catalin Marinas <catalin.marinas@arm.com> | 2018-02-06 17:53:42 -0500 |
commit | 91b2d3442f6a44dce875670d702af22737ad5eff (patch) | |
tree | b723651d1d77cee6e73d4d1a1898653f0801d6d4 | |
parent | f71c2ffcb20dd8626880747557014bb9a61eb90e (diff) |
arm64: futex: Mask __user pointers prior to dereference
The arm64 futex code has some explicit dereferencing of user pointers
where performing atomic operations in response to a futex command. This
patch uses masking to limit any speculative futex operations to within
the user address space.
Signed-off-by: Will Deacon <will.deacon@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
-rw-r--r-- | arch/arm64/include/asm/futex.h | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/arch/arm64/include/asm/futex.h b/arch/arm64/include/asm/futex.h index 5bb2fd4674e7..07fe2479d310 100644 --- a/arch/arm64/include/asm/futex.h +++ b/arch/arm64/include/asm/futex.h | |||
@@ -48,9 +48,10 @@ do { \ | |||
48 | } while (0) | 48 | } while (0) |
49 | 49 | ||
50 | static inline int | 50 | static inline int |
51 | arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | 51 | arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *_uaddr) |
52 | { | 52 | { |
53 | int oldval = 0, ret, tmp; | 53 | int oldval = 0, ret, tmp; |
54 | u32 __user *uaddr = __uaccess_mask_ptr(_uaddr); | ||
54 | 55 | ||
55 | pagefault_disable(); | 56 | pagefault_disable(); |
56 | 57 | ||
@@ -88,15 +89,17 @@ arch_futex_atomic_op_inuser(int op, int oparg, int *oval, u32 __user *uaddr) | |||
88 | } | 89 | } |
89 | 90 | ||
90 | static inline int | 91 | static inline int |
91 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, | 92 | futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *_uaddr, |
92 | u32 oldval, u32 newval) | 93 | u32 oldval, u32 newval) |
93 | { | 94 | { |
94 | int ret = 0; | 95 | int ret = 0; |
95 | u32 val, tmp; | 96 | u32 val, tmp; |
97 | u32 __user *uaddr; | ||
96 | 98 | ||
97 | if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32))) | 99 | if (!access_ok(VERIFY_WRITE, _uaddr, sizeof(u32))) |
98 | return -EFAULT; | 100 | return -EFAULT; |
99 | 101 | ||
102 | uaddr = __uaccess_mask_ptr(_uaddr); | ||
100 | uaccess_enable(); | 103 | uaccess_enable(); |
101 | asm volatile("// futex_atomic_cmpxchg_inatomic\n" | 104 | asm volatile("// futex_atomic_cmpxchg_inatomic\n" |
102 | " prfm pstl1strm, %2\n" | 105 | " prfm pstl1strm, %2\n" |