Skip to content

Commit 98b861a

Browse files
committed
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 <[email protected]> Acked-by: Geert Uytterhoeven <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]>
1 parent e93a1cb commit 98b861a

File tree

4 files changed

+15
-42
lines changed

4 files changed

+15
-42
lines changed

arch/h8300/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ config H8300
1111
select GENERIC_IRQ_SHOW
1212
select FRAME_POINTER
1313
select GENERIC_CPU_DEVICES
14+
select GENERIC_STRNCPY_FROM_USER
15+
select GENERIC_STRNLEN_USER
1416
select MODULES_USE_ELF_RELA
1517
select COMMON_CLK
1618
select ARCH_WANT_FRAME_POINTERS

arch/m68k/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ config M68K
1616
select GENERIC_CPU_DEVICES
1717
select GENERIC_IOMAP
1818
select GENERIC_IRQ_SHOW
19-
select GENERIC_STRNCPY_FROM_USER if MMU
20-
select GENERIC_STRNLEN_USER if MMU
19+
select GENERIC_STRNCPY_FROM_USER
20+
select GENERIC_STRNLEN_USER
2121
select HAVE_AOUT if MMU
2222
select HAVE_ASM_MODVERSIONS
2323
select HAVE_DEBUG_BUGVERBOSE

arch/riscv/Kconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ config RISCV
5656
select GENERIC_PTDUMP if MMU
5757
select GENERIC_SCHED_CLOCK
5858
select GENERIC_SMP_IDLE_THREAD
59-
select GENERIC_STRNCPY_FROM_USER if MMU
60-
select GENERIC_STRNLEN_USER if MMU
59+
select GENERIC_STRNCPY_FROM_USER
60+
select GENERIC_STRNLEN_USER
6161
select GENERIC_TIME_VSYSCALL if MMU && 64BIT
6262
select HANDLE_DOMAIN_IRQ
6363
select HAVE_ARCH_AUDITSYSCALL

include/asm-generic/uaccess.h

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ static inline void set_fs(mm_segment_t fs)
119119
#ifndef uaccess_kernel
120120
#define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
121121
#endif
122+
123+
#ifndef user_addr_max
124+
#define user_addr_max() (uaccess_kernel() ? ~0UL : TASK_SIZE)
125+
#endif
126+
122127
#endif /* CONFIG_SET_FS */
123128

124129
#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)
243248

244249
extern int __get_user_bad(void) __attribute__((noreturn));
245250

246-
/*
247-
* Copy a null terminated string from userspace.
248-
*/
249-
#ifndef strncpy_from_user
250-
static inline long
251-
strncpy_from_user(char *dst, const char __user *src, long count)
252-
{
253-
char *tmp;
254-
255-
if (!access_ok(src, 1))
256-
return -EFAULT;
257-
258-
strncpy(dst, (const char __force *)src, count);
259-
for (tmp = dst; *tmp && count > 0; tmp++, count--)
260-
;
261-
return (tmp - dst);
262-
}
263-
#endif
264-
265-
#ifndef strnlen_user
266-
/*
267-
* Return the size of a string (including the ending 0)
268-
*
269-
* Return 0 on exception, a value greater than N if too long
270-
*
271-
* Unlike strnlen, strnlen_user includes the nul terminator in
272-
* its returned count. Callers should check for a returned value
273-
* greater than N as an indication the string is too long.
274-
*/
275-
static inline long strnlen_user(const char __user *src, long n)
276-
{
277-
if (!access_ok(src, 1))
278-
return 0;
279-
280-
return strnlen(src, n) + 1;
281-
}
282-
#endif
283-
284251
/*
285252
* Zero Userspace
286253
*/
@@ -305,4 +272,8 @@ clear_user(void __user *to, unsigned long n)
305272

306273
#include <asm/extable.h>
307274

275+
__must_check long strncpy_from_user(char *dst, const char __user *src,
276+
long count);
277+
__must_check long strnlen_user(const char __user *src, long n);
278+
308279
#endif /* __ASM_GENERIC_UACCESS_H */

0 commit comments

Comments
 (0)