From 98b861a304318e60eea584bef123d924e5d0dcff Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Sat, 23 Jan 2021 15:21:22 +0100 Subject: asm-generic: uaccess: remove inline strncpy_from_user/strnlen_user The inline version is used on three NOMMU architectures and is particularly inefficient when it scans the string one byte at a time twice. It also lacks a check for user_addr_max(), but this is probably ok on NOMMU targets. Consolidate the asm-generic implementation with the library version that is used everywhere else. This version is generalized enough to work efficiently on both MMU and NOMMU targets, and using the same code everywhere reduces the potential for subtle bugs. Mark the prototypes as __must_check in the process. Reviewed-by: Geert Uytterhoeven Acked-by: Geert Uytterhoeven Reviewed-by: Christoph Hellwig Signed-off-by: Arnd Bergmann --- include/asm-generic/uaccess.h | 47 +++++++++---------------------------------- 1 file changed, 9 insertions(+), 38 deletions(-) (limited to 'include/asm-generic') diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h index 2f8a5d3bbd57..10ffa8b5c117 100644 --- a/include/asm-generic/uaccess.h +++ b/include/asm-generic/uaccess.h @@ -119,6 +119,11 @@ static inline void set_fs(mm_segment_t fs) #ifndef uaccess_kernel #define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg) #endif + +#ifndef user_addr_max +#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE) +#endif + #endif /* CONFIG_SET_FS */ #define access_ok(addr, size) __access_ok((unsigned long)(addr),(size)) @@ -243,44 +248,6 @@ static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) extern int __get_user_bad(void) __attribute__((noreturn)); -/* - * Copy a null terminated string from userspace. - */ -#ifndef strncpy_from_user -static inline long -strncpy_from_user(char *dst, const char __user *src, long count) -{ - char *tmp; - - if (!access_ok(src, 1)) - return -EFAULT; - - strncpy(dst, (const char __force *)src, count); - for (tmp = dst; *tmp && count > 0; tmp++, count--) - ; - return (tmp - dst); -} -#endif - -#ifndef strnlen_user -/* - * Return the size of a string (including the ending 0) - * - * Return 0 on exception, a value greater than N if too long - * - * Unlike strnlen, strnlen_user includes the nul terminator in - * its returned count. Callers should check for a returned value - * greater than N as an indication the string is too long. - */ -static inline long strnlen_user(const char __user *src, long n) -{ - if (!access_ok(src, 1)) - return 0; - - return strnlen(src, n) + 1; -} -#endif - /* * Zero Userspace */ @@ -305,4 +272,8 @@ clear_user(void __user *to, unsigned long n) #include +__must_check long strncpy_from_user(char *dst, const char __user *src, + long count); +__must_check long strnlen_user(const char __user *src, long n); + #endif /* __ASM_GENERIC_UACCESS_H */ -- cgit v1.2.3