Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86: remove __range_not_ok()

The __range_not_ok() helper is an x86 (and sparc64) specific interface
that does roughly the same thing as __access_ok(), but with different
calling conventions.

Change this to use the normal interface in order for consistency as we
clean up all access_ok() implementations.

This changes the limit from TASK_SIZE to TASK_SIZE_MAX, which Al points
out is the right thing do do here anyway.

The callers have to use __access_ok() instead of the normal access_ok()
though, because on x86 that contains a WARN_ON_IN_IRQ() check that cannot
be used inside of NMI context while tracing.

The check in copy_code() is not needed any more, because this one is
already done by copy_from_user_nmi().

Suggested-by: Al Viro <viro@zeniv.linux.org.uk>
Suggested-by: Christoph Hellwig <hch@infradead.org>
Link: https://lore.kernel.org/lkml/YgsUKcXGR7r4nINj@zeniv-ca.linux.org.uk/
Signed-off-by: Arnd Bergmann <arnd@arndb.de>

+9 -13
+1 -1
arch/x86/events/core.c
··· 2794 2794 static inline int 2795 2795 valid_user_frame(const void __user *fp, unsigned long size) 2796 2796 { 2797 - return (__range_not_ok(fp, size, TASK_SIZE) == 0); 2797 + return __access_ok(fp, size); 2798 2798 } 2799 2799 2800 2800 static unsigned long get_segment_base(unsigned int segment)
+6 -4
arch/x86/include/asm/uaccess.h
··· 16 16 * Test whether a block of memory is a valid user space address. 17 17 * Returns 0 if the range is valid, nonzero otherwise. 18 18 */ 19 - static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, unsigned long limit) 19 + static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size) 20 20 { 21 + unsigned long limit = TASK_SIZE_MAX; 22 + 21 23 /* 22 24 * If we have used "sizeof()" for the size, 23 25 * we know it won't overflow the limit (but ··· 37 35 return unlikely(addr > limit); 38 36 } 39 37 40 - #define __range_not_ok(addr, size, limit) \ 38 + #define __access_ok(addr, size) \ 41 39 ({ \ 42 40 __chk_user_ptr(addr); \ 43 - __chk_range_not_ok((unsigned long __force)(addr), size, limit); \ 41 + !__chk_range_not_ok((unsigned long __force)(addr), size); \ 44 42 }) 45 43 46 44 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP ··· 71 69 #define access_ok(addr, size) \ 72 70 ({ \ 73 71 WARN_ON_IN_IRQ(); \ 74 - likely(!__range_not_ok(addr, size, TASK_SIZE_MAX)); \ 72 + likely(__access_ok(addr, size)); \ 75 73 }) 76 74 77 75 extern int __get_user_1(void);
-6
arch/x86/kernel/dumpstack.c
··· 81 81 /* The user space code from other tasks cannot be accessed. */ 82 82 if (regs != task_pt_regs(current)) 83 83 return -EPERM; 84 - /* 85 - * Make sure userspace isn't trying to trick us into dumping kernel 86 - * memory by pointing the userspace instruction pointer at it. 87 - */ 88 - if (__chk_range_not_ok(src, nbytes, TASK_SIZE_MAX)) 89 - return -EINVAL; 90 84 91 85 /* 92 86 * Even if named copy_from_user_nmi() this can be invoked from
+1 -1
arch/x86/kernel/stacktrace.c
··· 90 90 { 91 91 int ret; 92 92 93 - if (__range_not_ok(fp, sizeof(*frame), TASK_SIZE)) 93 + if (!__access_ok(fp, sizeof(*frame))) 94 94 return 0; 95 95 96 96 ret = 1;
+1 -1
arch/x86/lib/usercopy.c
··· 32 32 { 33 33 unsigned long ret; 34 34 35 - if (__range_not_ok(from, n, TASK_SIZE)) 35 + if (!__access_ok(from, n)) 36 36 return n; 37 37 38 38 if (!nmi_uaccess_okay())