summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-12-17 12:57:27 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2015-12-17 12:57:27 -0500
commit5b24a7a2aa2040c8c50c3b71122901d01661ff78 (patch)
treeb7c953730df4a96ee18ed4d082fee57fb9ad305a
parent11f1a4b9755f5dbc3e822a96502ebe9b044b14d8 (diff)
Add 'unsafe' user access functions for batched accesses
The naming is meant to discourage random use: the helper functions are not really any more "unsafe" than the traditional double-underscore functions (which need the address range checking), but they do need even more infrastructure around them, and should not be used willy-nilly. In addition to checking the access range, these user access functions require that you wrap the user access with a "user_acess_{begin,end}()" around it. That allows architectures that implement kernel user access control (x86: SMAP, arm64: PAN) to do the user access control in the wrapping user_access_begin/end part, and then batch up the actual user space accesses using the new interfaces. The main (and hopefully only) use for these are for core generic access helpers, initially just the generic user string functions (strnlen_user() and strncpy_from_user()). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--arch/x86/include/asm/uaccess.h25
-rw-r--r--include/linux/uaccess.h7
2 files changed, 32 insertions, 0 deletions
diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index cc228f4713da..ca59e4f9254e 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -762,5 +762,30 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
762#undef __copy_from_user_overflow 762#undef __copy_from_user_overflow
763#undef __copy_to_user_overflow 763#undef __copy_to_user_overflow
764 764
765/*
766 * The "unsafe" user accesses aren't really "unsafe", but the naming
767 * is a big fat warning: you have to not only do the access_ok()
768 * checking before using them, but you have to surround them with the
769 * user_access_begin/end() pair.
770 */
771#define user_access_begin() __uaccess_begin()
772#define user_access_end() __uaccess_end()
773
774#define unsafe_put_user(x, ptr) \
775({ \
776 int __pu_err; \
777 __put_user_size((x), (ptr), sizeof(*(ptr)), __pu_err, -EFAULT); \
778 __builtin_expect(__pu_err, 0); \
779})
780
781#define unsafe_get_user(x, ptr) \
782({ \
783 int __gu_err; \
784 unsigned long __gu_val; \
785 __get_user_size(__gu_val, (ptr), sizeof(*(ptr)), __gu_err, -EFAULT); \
786 (x) = (__force __typeof__(*(ptr)))__gu_val; \
787 __builtin_expect(__gu_err, 0); \
788})
789
765#endif /* _ASM_X86_UACCESS_H */ 790#endif /* _ASM_X86_UACCESS_H */
766 791
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 558129af828a..349557825428 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -111,4 +111,11 @@ extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
111#define probe_kernel_address(addr, retval) \ 111#define probe_kernel_address(addr, retval) \
112 probe_kernel_read(&retval, addr, sizeof(retval)) 112 probe_kernel_read(&retval, addr, sizeof(retval))
113 113
114#ifndef user_access_begin
115#define user_access_begin() do { } while (0)
116#define user_access_end() do { } while (0)
117#define unsafe_get_user(x, ptr) __get_user(x, ptr)
118#define unsafe_put_user(x, ptr) __put_user(x, ptr)
119#endif
120
114#endif /* __LINUX_UACCESS_H__ */ 121#endif /* __LINUX_UACCESS_H__ */