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 <geert@linux-m68k.org> Acked-by: Geert Uytterhoeven <geert@linux-m68k.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Родитель
e93a1cb8d2
Коммит
98b861a304
|
@ -11,6 +11,8 @@ config H8300
|
|||
select GENERIC_IRQ_SHOW
|
||||
select FRAME_POINTER
|
||||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_STRNCPY_FROM_USER
|
||||
select GENERIC_STRNLEN_USER
|
||||
select MODULES_USE_ELF_RELA
|
||||
select COMMON_CLK
|
||||
select ARCH_WANT_FRAME_POINTERS
|
||||
|
|
|
@ -16,8 +16,8 @@ config M68K
|
|||
select GENERIC_CPU_DEVICES
|
||||
select GENERIC_IOMAP
|
||||
select GENERIC_IRQ_SHOW
|
||||
select GENERIC_STRNCPY_FROM_USER if MMU
|
||||
select GENERIC_STRNLEN_USER if MMU
|
||||
select GENERIC_STRNCPY_FROM_USER
|
||||
select GENERIC_STRNLEN_USER
|
||||
select HAVE_AOUT if MMU
|
||||
select HAVE_ASM_MODVERSIONS
|
||||
select HAVE_DEBUG_BUGVERBOSE
|
||||
|
|
|
@ -56,8 +56,8 @@ config RISCV
|
|||
select GENERIC_PTDUMP if MMU
|
||||
select GENERIC_SCHED_CLOCK
|
||||
select GENERIC_SMP_IDLE_THREAD
|
||||
select GENERIC_STRNCPY_FROM_USER if MMU
|
||||
select GENERIC_STRNLEN_USER if MMU
|
||||
select GENERIC_STRNCPY_FROM_USER
|
||||
select GENERIC_STRNLEN_USER
|
||||
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
|
||||
select HANDLE_DOMAIN_IRQ
|
||||
select HAVE_ARCH_AUDITSYSCALL
|
||||
|
|
|
@ -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 <asm/extable.h>
|
||||
|
||||
__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 */
|
||||
|
|
Загрузка…
Ссылка в новой задаче