diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arc/include/asm/uaccess.h | 14 | ||||
-rw-r--r-- | arch/csky/include/asm/uaccess.h | 8 | ||||
-rw-r--r-- | arch/csky/lib/usercopy.c | 14 | ||||
-rw-r--r-- | arch/hexagon/include/asm/uaccess.h | 22 | ||||
-rw-r--r-- | arch/um/include/asm/uaccess.h | 8 | ||||
-rw-r--r-- | arch/um/kernel/skas/uaccess.c | 14 |
6 files changed, 51 insertions, 29 deletions
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h index ea40ec7f6cae..3476348f361e 100644 --- a/arch/arc/include/asm/uaccess.h +++ b/arch/arc/include/asm/uaccess.h @@ -661,6 +661,9 @@ __arc_strncpy_from_user(char *dst, const char __user *src, long count) long res = 0; char val; + if (!access_ok(src, 1)) + return -EFAULT; + if (count == 0) return 0; @@ -693,6 +696,9 @@ static inline long __arc_strnlen_user(const char __user *s, long n) long res, tmp1, cnt; char val; + if (!access_ok(s, 1)) + return 0; + __asm__ __volatile__( " mov %2, %1 \n" "1: ldb.ab %3, [%0, 1] \n" @@ -724,8 +730,8 @@ static inline long __arc_strnlen_user(const char __user *s, long n) #define INLINE_COPY_FROM_USER #define __clear_user(d, n) __arc_clear_user(d, n) -#define __strncpy_from_user(d, s, n) __arc_strncpy_from_user(d, s, n) -#define __strnlen_user(s, n) __arc_strnlen_user(s, n) +#define strncpy_from_user(d, s, n) __arc_strncpy_from_user(d, s, n) +#define strnlen_user(s, n) __arc_strnlen_user(s, n) #else extern unsigned long arc_clear_user_noinline(void __user *to, unsigned long n); @@ -734,8 +740,8 @@ extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src, extern long arc_strnlen_user_noinline(const char __user *src, long n); #define __clear_user(d, n) arc_clear_user_noinline(d, n) -#define __strncpy_from_user(d, s, n) arc_strncpy_from_user_noinline(d, s, n) -#define __strnlen_user(s, n) arc_strnlen_user_noinline(s, n) +#define strncpy_from_user(d, s, n) arc_strncpy_from_user_noinline(d, s, n) +#define strnlen_user(s, n) arc_strnlen_user_noinline(s, n) #endif diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h index ac83823fc437..e17c02a6709f 100644 --- a/arch/csky/include/asm/uaccess.h +++ b/arch/csky/include/asm/uaccess.h @@ -209,11 +209,11 @@ unsigned long raw_copy_to_user(void *to, const void *from, unsigned long n); unsigned long __clear_user(void __user *to, unsigned long n); #define __clear_user __clear_user -long __strncpy_from_user(char *dst, const char *src, long count); -#define __strncpy_from_user __strncpy_from_user +long strncpy_from_user(char *dst, const char *src, long count); +#define strncpy_from_user strncpy_from_user -long __strnlen_user(const char *s, long n); -#define __strnlen_user __strnlen_user +long strnlen_user(const char *s, long n); +#define strnlen_user strnlen_user #include <asm/segment.h> #include <asm-generic/uaccess.h> diff --git a/arch/csky/lib/usercopy.c b/arch/csky/lib/usercopy.c index c5d394a0ae78..05b36e9fd7d3 100644 --- a/arch/csky/lib/usercopy.c +++ b/arch/csky/lib/usercopy.c @@ -163,11 +163,14 @@ EXPORT_SYMBOL(raw_copy_to_user); * If @count is smaller than the length of the string, copies @count bytes * and returns @count. */ -long __strncpy_from_user(char *dst, const char *src, long count) +long strncpy_from_user(char *dst, const char *src, long count) { long res, faultres; int tmp; + if (!access_ok(s, 1)) + return -EFAULT; + __asm__ __volatile__( " cmpnei %3, 0 \n" " bf 4f \n" @@ -198,7 +201,7 @@ long __strncpy_from_user(char *dst, const char *src, long count) return res; } -EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(strncpy_from_user); /* * strnlen_user: - Get the size of a string in user space. @@ -211,10 +214,13 @@ EXPORT_SYMBOL(__strncpy_from_user); * On exception, returns 0. * If the string is too long, returns a value greater than @n. */ -long __strnlen_user(const char *s, long n) +long strnlen_user(const char *s, long n) { unsigned long res, tmp; + if (!access_ok(s, 1)) + return -EFAULT; + __asm__ __volatile__( " cmpnei %1, 0 \n" " bf 3f \n" @@ -242,7 +248,7 @@ long __strnlen_user(const char *s, long n) return res; } -EXPORT_SYMBOL(__strnlen_user); +EXPORT_SYMBOL(strnlen_user); /* * __clear_user: - Zero a block of memory in user space, with less checking. diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h index c1019a736ff1..59aa3a50744f 100644 --- a/arch/hexagon/include/asm/uaccess.h +++ b/arch/hexagon/include/asm/uaccess.h @@ -57,23 +57,27 @@ unsigned long raw_copy_to_user(void __user *to, const void *from, __kernel_size_t __clear_user_hexagon(void __user *dest, unsigned long count); #define __clear_user(a, s) __clear_user_hexagon((a), (s)) -#define __strncpy_from_user(dst, src, n) hexagon_strncpy_from_user(dst, src, n) +extern long __strnlen_user(const char __user *src, long n); -/* get around the ifndef in asm-generic/uaccess.h */ -#define __strnlen_user __strnlen_user +static inline strnlen_user(const char __user *src, long n) +{ + if (!access_ok(src, 1)) + return 0; -extern long __strnlen_user(const char __user *src, long n); + return __strnlen_user(src, n); +} +/* get around the ifndef in asm-generic/uaccess.h */ +#define strnlen_user strnlen_user -static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, - long n); +static inline long strncpy_from_user(char *dst, const char __user *src, long n); +#define strncpy_from_user strncpy_from_user #include <asm-generic/uaccess.h> /* Todo: an actual accelerated version of this. */ -static inline long hexagon_strncpy_from_user(char *dst, const char __user *src, - long n) +static inline long strncpy_from_user(char *dst, const char __user *src, long n) { - long res = __strnlen_user(src, n); + long res = strnlen_user(src, n); if (unlikely(!res)) return -EFAULT; diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index fe66d659acad..3bf209f683f8 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h @@ -23,16 +23,16 @@ extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n); extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n); -extern long __strncpy_from_user(char *dst, const char __user *src, long count); -extern long __strnlen_user(const void __user *str, long len); +extern long strncpy_from_user(char *dst, const char __user *src, long count); +extern long strnlen_user(const void __user *str, long len); extern unsigned long __clear_user(void __user *mem, unsigned long len); static inline int __access_ok(unsigned long addr, unsigned long size); /* Teach asm-generic/uaccess.h that we have C functions for these. */ #define __access_ok __access_ok #define __clear_user __clear_user -#define __strnlen_user __strnlen_user -#define __strncpy_from_user __strncpy_from_user +#define strnlen_user strnlen_user +#define strncpy_from_user strncpy_from_user #define INLINE_COPY_FROM_USER #define INLINE_COPY_TO_USER diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index 6c76df96e858..a509be911026 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c @@ -189,11 +189,14 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) return 0; } -long __strncpy_from_user(char *dst, const char __user *src, long count) +long strncpy_from_user(char *dst, const char __user *src, long count) { long n; char *ptr = dst; + if (!access_ok(src, 1)) + return -EFAULT; + if (uaccess_kernel()) { strncpy(dst, (__force void *) src, count); return strnlen(dst, count); @@ -205,7 +208,7 @@ long __strncpy_from_user(char *dst, const char __user *src, long count) return -EFAULT; return strnlen(dst, count); } -EXPORT_SYMBOL(__strncpy_from_user); +EXPORT_SYMBOL(strncpy_from_user); static int clear_chunk(unsigned long addr, int len, void *unused) { @@ -236,10 +239,13 @@ static int strnlen_chunk(unsigned long str, int len, void *arg) return 0; } -long __strnlen_user(const void __user *str, long len) +long strnlen_user(const char __user *str, long len) { int count = 0, n; + if (!access_ok(str, 1)) + return -EFAULT; + if (uaccess_kernel()) return strnlen((__force char*)str, len) + 1; @@ -248,7 +254,7 @@ long __strnlen_user(const void __user *str, long len) return count + 1; return 0; } -EXPORT_SYMBOL(__strnlen_user); +EXPORT_SYMBOL(strnlen_user); /** * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant |