summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/Kconfig2
-rw-r--r--arch/arc/include/asm/uaccess.h72
-rw-r--r--arch/arc/mm/extable.c12
-rw-r--r--arch/arm/Kconfig2
-rw-r--r--arch/arm64/Kconfig2
-rw-r--r--arch/csky/include/asm/uaccess.h6
-rw-r--r--arch/csky/lib/usercopy.c102
-rw-r--r--arch/h8300/kernel/h8300_ksyms.c2
-rw-r--r--arch/h8300/lib/Makefile2
-rw-r--r--arch/h8300/lib/strncpy.S35
-rw-r--r--arch/hexagon/include/asm/uaccess.h31
-rw-r--r--arch/hexagon/kernel/hexagon_ksyms.c1
-rw-r--r--arch/hexagon/mm/Makefile2
-rw-r--r--arch/hexagon/mm/strnlen_user.S126
-rw-r--r--arch/ia64/Kconfig2
-rw-r--r--arch/m68k/Kconfig2
-rw-r--r--arch/microblaze/include/asm/uaccess.h21
-rw-r--r--arch/microblaze/kernel/microblaze_ksyms.c1
-rw-r--r--arch/microblaze/lib/uaccess_old.S90
-rw-r--r--arch/mips/Kconfig2
-rw-r--r--arch/nds32/Kconfig2
-rw-r--r--arch/nios2/Kconfig2
-rw-r--r--arch/openrisc/Kconfig2
-rw-r--r--arch/parisc/Kconfig2
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/riscv/Kconfig2
-rw-r--r--arch/s390/include/asm/uaccess.h18
-rw-r--r--arch/s390/lib/uaccess.c52
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sparc/Kconfig2
-rw-r--r--arch/um/Kconfig2
-rw-r--r--arch/um/include/asm/uaccess.h5
-rw-r--r--arch/um/kernel/skas/uaccess.c14
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/xtensa/Kconfig3
-rw-r--r--arch/xtensa/include/asm/uaccess.h3
-rw-r--r--arch/xtensa/kernel/xtensa_ksyms.c2
-rw-r--r--include/asm-generic/bitops/builtin-ffs.h2
-rw-r--r--include/asm-generic/bitops/ffs.h2
-rw-r--r--include/asm-generic/bitops/non-atomic.h14
-rw-r--r--include/asm-generic/uaccess.h53
-rw-r--r--lib/Kconfig10
42 files changed, 56 insertions, 657 deletions
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 6c50877841df..02e5b673bdad 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -28,8 +28,6 @@ config ALPHA
select AUDIT_ARCH
select GENERIC_CPU_VULNERABILITIES
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select HAVE_ARCH_AUDITSYSCALL
select HAVE_MOD_ARCH_SPECIFIC
select MODULES_USE_ELF_RELA
diff --git a/arch/arc/include/asm/uaccess.h b/arch/arc/include/asm/uaccess.h
index ea40ec7f6cae..783bfdb3bfa3 100644
--- a/arch/arc/include/asm/uaccess.h
+++ b/arch/arc/include/asm/uaccess.h
@@ -655,88 +655,16 @@ static inline unsigned long __arc_clear_user(void __user *to, unsigned long n)
return res;
}
-static inline long
-__arc_strncpy_from_user(char *dst, const char __user *src, long count)
-{
- long res = 0;
- char val;
-
- if (count == 0)
- return 0;
-
- __asm__ __volatile__(
- " mov lp_count, %5 \n"
- " lp 3f \n"
- "1: ldb.ab %3, [%2, 1] \n"
- " breq.d %3, 0, 3f \n"
- " stb.ab %3, [%1, 1] \n"
- " add %0, %0, 1 # Num of NON NULL bytes copied \n"
- "3: \n"
- " .section .fixup, \"ax\" \n"
- " .align 4 \n"
- "4: mov %0, %4 # sets @res as -EFAULT \n"
- " j 3b \n"
- " .previous \n"
- " .section __ex_table, \"a\" \n"
- " .align 4 \n"
- " .word 1b, 4b \n"
- " .previous \n"
- : "+r"(res), "+r"(dst), "+r"(src), "=r"(val)
- : "g"(-EFAULT), "r"(count)
- : "lp_count", "memory");
-
- return res;
-}
-
-static inline long __arc_strnlen_user(const char __user *s, long n)
-{
- long res, tmp1, cnt;
- char val;
-
- __asm__ __volatile__(
- " mov %2, %1 \n"
- "1: ldb.ab %3, [%0, 1] \n"
- " breq.d %3, 0, 2f \n"
- " sub.f %2, %2, 1 \n"
- " bnz 1b \n"
- " sub %2, %2, 1 \n"
- "2: sub %0, %1, %2 \n"
- "3: ;nop \n"
- " .section .fixup, \"ax\" \n"
- " .align 4 \n"
- "4: mov %0, 0 \n"
- " j 3b \n"
- " .previous \n"
- " .section __ex_table, \"a\" \n"
- " .align 4 \n"
- " .word 1b, 4b \n"
- " .previous \n"
- : "=r"(res), "=r"(tmp1), "=r"(cnt), "=r"(val)
- : "0"(s), "1"(n)
- : "memory");
-
- return res;
-}
-
#ifndef CONFIG_CC_OPTIMIZE_FOR_SIZE
#define INLINE_COPY_TO_USER
#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)
#else
extern unsigned long arc_clear_user_noinline(void __user *to,
unsigned long n);
-extern long arc_strncpy_from_user_noinline (char *dst, const char __user *src,
- long count);
-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)
-
#endif
#include <asm/segment.h>
diff --git a/arch/arc/mm/extable.c b/arch/arc/mm/extable.c
index b06b09ddf924..4e14c4244ea2 100644
--- a/arch/arc/mm/extable.c
+++ b/arch/arc/mm/extable.c
@@ -32,16 +32,4 @@ unsigned long arc_clear_user_noinline(void __user *to,
}
EXPORT_SYMBOL(arc_clear_user_noinline);
-long arc_strncpy_from_user_noinline(char *dst, const char __user *src,
- long count)
-{
- return __arc_strncpy_from_user(dst, src, count);
-}
-EXPORT_SYMBOL(arc_strncpy_from_user_noinline);
-
-long arc_strnlen_user_noinline(const char __user *src, long n)
-{
- return __arc_strnlen_user(src, n);
-}
-EXPORT_SYMBOL(arc_strnlen_user_noinline);
#endif
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 2fb7012c3246..1a48c17a5909 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -63,8 +63,6 @@ config ARM
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL if AEABI && !OABI_COMPAT
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 62c3c1d2190f..9dc1720a909f 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -130,8 +130,6 @@ config ARM64
select GENERIC_PTDUMP
select GENERIC_SCHED_CLOCK
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_TIME_NS
diff --git a/arch/csky/include/asm/uaccess.h b/arch/csky/include/asm/uaccess.h
index ac83823fc437..c40f06ee8d3e 100644
--- a/arch/csky/include/asm/uaccess.h
+++ b/arch/csky/include/asm/uaccess.h
@@ -209,12 +209,6 @@ 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 __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..3c01c54421ca 100644
--- a/arch/csky/lib/usercopy.c
+++ b/arch/csky/lib/usercopy.c
@@ -143,108 +143,6 @@ unsigned long raw_copy_to_user(void *to, const void *from,
EXPORT_SYMBOL(raw_copy_to_user);
/*
- * __strncpy_from_user: - Copy a NUL terminated string from userspace,
- * with less checking.
- * @dst: Destination address, in kernel space. This buffer must be at
- * least @count bytes long.
- * @src: Source address, in user space.
- * @count: Maximum number of bytes to copy, including the trailing NUL.
- *
- * Copies a NUL-terminated string from userspace to kernel space.
- * Caller must check the specified block with access_ok() before calling
- * this function.
- *
- * On success, returns the length of the string (not including the trailing
- * NUL).
- *
- * If access to userspace fails, returns -EFAULT (some data may have been
- * copied).
- *
- * 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 res, faultres;
- int tmp;
-
- __asm__ __volatile__(
- " cmpnei %3, 0 \n"
- " bf 4f \n"
- "1: cmpnei %1, 0 \n"
- " bf 5f \n"
- "2: ldb %4, (%3, 0) \n"
- " stb %4, (%2, 0) \n"
- " cmpnei %4, 0 \n"
- " bf 3f \n"
- " addi %3, 1 \n"
- " addi %2, 1 \n"
- " subi %1, 1 \n"
- " br 1b \n"
- "3: subu %0, %1 \n"
- " br 5f \n"
- "4: mov %0, %5 \n"
- " br 5f \n"
- ".section __ex_table, \"a\" \n"
- ".align 2 \n"
- ".long 2b, 4b \n"
- ".previous \n"
- "5: \n"
- : "=r"(res), "=r"(count), "=r"(dst),
- "=r"(src), "=r"(tmp), "=r"(faultres)
- : "5"(-EFAULT), "0"(count), "1"(count),
- "2"(dst), "3"(src)
- : "memory");
-
- return res;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
-
-/*
- * strnlen_user: - Get the size of a string in user space.
- * @str: The string to measure.
- * @n: The maximum valid length
- *
- * Get the size of a NUL-terminated string in user space.
- *
- * Returns the size of the string INCLUDING the terminating NUL.
- * On exception, returns 0.
- * If the string is too long, returns a value greater than @n.
- */
-long __strnlen_user(const char *s, long n)
-{
- unsigned long res, tmp;
-
- __asm__ __volatile__(
- " cmpnei %1, 0 \n"
- " bf 3f \n"
- "1: cmpnei %0, 0 \n"
- " bf 3f \n"
- "2: ldb %3, (%1, 0) \n"
- " cmpnei %3, 0 \n"
- " bf 3f \n"
- " subi %0, 1 \n"
- " addi %1, 1 \n"
- " br 1b \n"
- "3: subu %2, %0 \n"
- " addi %2, 1 \n"
- " br 5f \n"
- "4: movi %0, 0 \n"
- " br 5f \n"
- ".section __ex_table, \"a\" \n"
- ".align 2 \n"
- ".long 2b, 4b \n"
- ".previous \n"
- "5: \n"
- : "=r"(n), "=r"(s), "=r"(res), "=r"(tmp)
- : "0"(n), "1"(s), "2"(n)
- : "memory");
-
- return res;
-}
-EXPORT_SYMBOL(__strnlen_user);
-
-/*
* __clear_user: - Zero a block of memory in user space, with less checking.
* @to: Destination address, in user space.
* @n: Number of bytes to zero.
diff --git a/arch/h8300/kernel/h8300_ksyms.c b/arch/h8300/kernel/h8300_ksyms.c
index 1c6f902e82a5..853d6e886477 100644
--- a/arch/h8300/kernel/h8300_ksyms.c
+++ b/arch/h8300/kernel/h8300_ksyms.c
@@ -19,7 +19,6 @@ asmlinkage long __mulsi3(long, long);
asmlinkage long __udivsi3(long, long);
asmlinkage void *memcpy(void *, const void *, size_t);
asmlinkage void *memset(void *, int, size_t);
-asmlinkage long strncpy_from_user(void *to, void *from, size_t n);
/* gcc lib functions */
EXPORT_SYMBOL(__ucmpdi2);
@@ -34,4 +33,3 @@ EXPORT_SYMBOL(__mulsi3);
EXPORT_SYMBOL(__udivsi3);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(strncpy_from_user);
diff --git a/arch/h8300/lib/Makefile b/arch/h8300/lib/Makefile
index 685fa837c1f7..5911c1fa856d 100644
--- a/arch/h8300/lib/Makefile
+++ b/arch/h8300/lib/Makefile
@@ -3,7 +3,7 @@
# Makefile for H8/300-specific library files..
#
-lib-y = memcpy.o memset.o abs.o strncpy.o \
+lib-y = memcpy.o memset.o abs.o \
mulsi3.o udivsi3.o muldi3.o moddivsi3.o \
ashldi3.o lshrdi3.o ashrdi3.o ucmpdi2.o \
delay.o
diff --git a/arch/h8300/lib/strncpy.S b/arch/h8300/lib/strncpy.S
deleted file mode 100644
index 8b65d7c4727b..000000000000
--- a/arch/h8300/lib/strncpy.S
+++ /dev/null
@@ -1,35 +0,0 @@
-;;; SPDX-License-Identifier: GPL-2.0
-;;; strncpy.S
-
-#include <asm/linkage.h>
-
- .text
-.global strncpy_from_user
-
-;;; long strncpy_from_user(void *to, void *from, size_t n)
-strncpy_from_user:
- mov.l er2,er2
- bne 1f
- sub.l er0,er0
- rts
-1:
- mov.l er4,@-sp
- sub.l er3,er3
-2:
- mov.b @er1+,r4l
- mov.b r4l,@er0
- adds #1,er0
- beq 3f
- inc.l #1,er3
- dec.l #1,er2
- bne 2b
-3:
- dec.l #1,er2
-4:
- mov.b r4l,@er0
- adds #1,er0
- dec.l #1,er2
- bne 4b
- mov.l er3,er0
- mov.l @sp+,er4
- rts
diff --git a/arch/hexagon/include/asm/uaccess.h b/arch/hexagon/include/asm/uaccess.h
index c1019a736ff1..ef5bfef8d490 100644
--- a/arch/hexagon/include/asm/uaccess.h
+++ b/arch/hexagon/include/asm/uaccess.h
@@ -57,38 +57,7 @@ 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)
-
-/* get around the ifndef in asm-generic/uaccess.h */
-#define __strnlen_user __strnlen_user
-
-extern long __strnlen_user(const char __user *src, long n);
-
-static inline long hexagon_strncpy_from_user(char *dst, const char __user *src,
- long n);
-
#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)
-{
- long res = __strnlen_user(src, n);
-
- if (unlikely(!res))
- return -EFAULT;
-
- if (res > n) {
- long left = raw_copy_from_user(dst, src, n);
- if (unlikely(left))
- memset(dst + (n - left), 0, left);
- return n;
- } else {
- long left = raw_copy_from_user(dst, src, res);
- if (unlikely(left))
- memset(dst + (res - left), 0, left);
- return res-1;
- }
-}
#endif
diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c
index 35545a7386a0..ec56ce2d92a2 100644
--- a/arch/hexagon/kernel/hexagon_ksyms.c
+++ b/arch/hexagon/kernel/hexagon_ksyms.c
@@ -15,7 +15,6 @@ EXPORT_SYMBOL(__clear_user_hexagon);
EXPORT_SYMBOL(raw_copy_from_user);
EXPORT_SYMBOL(raw_copy_to_user);
EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(__vmgetie);
EXPORT_SYMBOL(__vmsetie);
EXPORT_SYMBOL(__vmyield);
diff --git a/arch/hexagon/mm/Makefile b/arch/hexagon/mm/Makefile
index 893838499591..49911a906fd0 100644
--- a/arch/hexagon/mm/Makefile
+++ b/arch/hexagon/mm/Makefile
@@ -4,4 +4,4 @@
#
obj-y := init.o ioremap.o uaccess.o vm_fault.o cache.o
-obj-y += copy_to_user.o copy_from_user.o strnlen_user.o vm_tlb.o
+obj-y += copy_to_user.o copy_from_user.o vm_tlb.o
diff --git a/arch/hexagon/mm/strnlen_user.S b/arch/hexagon/mm/strnlen_user.S
deleted file mode 100644
index 4b5574a7cc9c..000000000000
--- a/arch/hexagon/mm/strnlen_user.S
+++ /dev/null
@@ -1,126 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * User string length functions for kernel
- *
- * Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
- */
-
-#define isrc r0
-#define max r1 /* Do not change! */
-
-#define end r2
-#define tmp1 r3
-
-#define obo r6 /* off-by-one */
-#define start r7
-#define mod8 r8
-#define dbuf r15:14
-#define dcmp r13:12
-
-/*
- * The vector mask version of this turned out *really* badly.
- * The hardware loop version also turned out *really* badly.
- * Seems straight pointer arithmetic basically wins here.
- */
-
-#define fname __strnlen_user
-
- .text
- .global fname
- .type fname, @function
- .p2align 5 /* why? */
-fname:
- {
- mod8 = and(isrc,#7);
- end = add(isrc,max);
- start = isrc;
- }
- {
- P0 = cmp.eq(mod8,#0);
- mod8 = and(end,#7);
- dcmp = #0;
- if (P0.new) jump:t dw_loop; /* fire up the oven */
- }
-
-alignment_loop:
-fail_1: {
- tmp1 = memb(start++#1);
- }
- {
- P0 = cmp.eq(tmp1,#0);
- if (P0.new) jump:nt exit_found;
- P1 = cmp.gtu(end,start);
- mod8 = and(start,#7);
- }
- {
- if (!P1) jump exit_error; /* hit the end */
- P0 = cmp.eq(mod8,#0);
- }
- {
- if (!P0) jump alignment_loop;
- }
-
-
-
-dw_loop:
-fail_2: {
- dbuf = memd(start);
- obo = add(start,#1);
- }
- {
- P0 = vcmpb.eq(dbuf,dcmp);
- }
- {
- tmp1 = P0;
- P0 = cmp.gtu(end,start);
- }
- {
- tmp1 = ct0(tmp1);
- mod8 = and(end,#7);
- if (!P0) jump end_check;
- }
- {
- P0 = cmp.eq(tmp1,#32);
- if (!P0.new) jump:nt exit_found;
- if (!P0.new) start = add(obo,tmp1);
- }
- {
- start = add(start,#8);
- jump dw_loop;
- } /* might be nice to combine these jumps... */
-
-
-end_check:
- {
- P0 = cmp.gt(tmp1,mod8);
- if (P0.new) jump:nt exit_error; /* neverfound! */
- start = add(obo,tmp1);
- }
-
-exit_found:
- {
- R0 = sub(start,isrc);
- jumpr R31;
- }
-
-exit_error:
- {
- R0 = add(max,#1);
- jumpr R31;
- }
-
- /* Uh, what does the "fixup" return here? */
- .falign
-fix_1:
- {
- R0 = #0;
- jumpr R31;
- }
-
- .size fname,.-fname
-
-
-.section __ex_table,"a"
-.long fail_1,fix_1
-.long fail_2,fix_1
-.previous
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 4993c7ac7ff6..045792cde481 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -9,6 +9,8 @@ menu "Processor type and features"
config IA64
bool
select ARCH_HAS_DMA_MARK_CLEAN
+ select ARCH_HAS_STRNCPY_FROM_USER
+ select ARCH_HAS_STRNLEN_USER
select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO
select ACPI
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index d632a1d576f9..774c35f47eea 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -16,8 +16,6 @@ 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 HAVE_AOUT if MMU
select HAVE_ASM_MODVERSIONS
select HAVE_DEBUG_BUGVERBOSE
diff --git a/arch/microblaze/include/asm/uaccess.h b/arch/microblaze/include/asm/uaccess.h
index c44b59470e45..d2a8ef9f8978 100644
--- a/arch/microblaze/include/asm/uaccess.h
+++ b/arch/microblaze/include/asm/uaccess.h
@@ -35,6 +35,7 @@
# define get_fs() (current_thread_info()->addr_limit)
# define set_fs(val) (current_thread_info()->addr_limit = (val))
+# define user_addr_max() get_fs().seg
# define uaccess_kernel() (get_fs().seg == KERNEL_DS.seg)
@@ -296,28 +297,14 @@ raw_copy_to_user(void __user *to, const void *from, unsigned long n)
/*
* Copy a null terminated string from userspace.
*/
-extern int __strncpy_user(char *to, const char __user *from, int len);
-
-static inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
- if (!access_ok(src, 1))
- return -EFAULT;
- return __strncpy_user(dst, src, count);
-}
+__must_check long strncpy_from_user(char *dst, const char __user *src,
+ long count);
/*
* Return the size of a string (including the ending 0)
*
* Return 0 on exception, a value greater than N if too long
*/
-extern int __strnlen_user(const char __user *sstr, int len);
-
-static inline long strnlen_user(const char __user *src, long n)
-{
- if (!access_ok(src, 1))
- return 0;
- return __strnlen_user(src, n);
-}
+__must_check long strnlen_user(const char __user *sstr, long len);
#endif /* _ASM_MICROBLAZE_UACCESS_H */
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c
index 303aaf13573b..c892e173ec99 100644
--- a/arch/microblaze/kernel/microblaze_ksyms.c
+++ b/arch/microblaze/kernel/microblaze_ksyms.c
@@ -26,7 +26,6 @@ EXPORT_SYMBOL(_mcount);
* Assembly functions that may be used (directly or indirectly) by modules
*/
EXPORT_SYMBOL(__copy_tofrom_user);
-EXPORT_SYMBOL(__strncpy_user);
#ifdef CONFIG_OPT_LIB_ASM
EXPORT_SYMBOL(memcpy);
diff --git a/arch/microblaze/lib/uaccess_old.S b/arch/microblaze/lib/uaccess_old.S
index eca290090038..dd5f3bfbc2c5 100644
--- a/arch/microblaze/lib/uaccess_old.S
+++ b/arch/microblaze/lib/uaccess_old.S
@@ -12,96 +12,6 @@
#include <linux/linkage.h>
#include <asm/page.h>
-/*
- * int __strncpy_user(char *to, char *from, int len);
- *
- * Returns:
- * -EFAULT for an exception
- * len if we hit the buffer limit
- * bytes copied
- */
-
- .text
-.globl __strncpy_user;
-.type __strncpy_user, @function
-.align 4;
-__strncpy_user:
-
- /*
- * r5 - to
- * r6 - from
- * r7 - len
- * r3 - temp count
- * r4 - temp val
- */
- beqid r7,3f
- addik r3,r7,0 /* temp_count = len */
-1:
- lbu r4,r6,r0
- beqid r4,2f
- sb r4,r5,r0
-
- addik r5,r5,1
- addik r6,r6,1 /* delay slot */
-
- addik r3,r3,-1
- bnei r3,1b /* break on len */
-2:
- rsubk r3,r3,r7 /* temp_count = len - temp_count */
-3:
- rtsd r15,8
- nop
- .size __strncpy_user, . - __strncpy_user
-
- .section .fixup, "ax"
- .align 2
-4:
- brid 3b
- addik r3,r0, -EFAULT
-
- .section __ex_table, "a"
- .word 1b,4b
-
-/*
- * int __strnlen_user(char __user *str, int maxlen);
- *
- * Returns:
- * 0 on error
- * maxlen + 1 if no NUL byte found within maxlen bytes
- * size of the string (including NUL byte)
- */
-
- .text
-.globl __strnlen_user;
-.type __strnlen_user, @function
-.align 4;
-__strnlen_user:
- beqid r6,3f
- addik r3,r6,0
-1:
- lbu r4,r5,r0
- beqid r4,2f /* break on NUL */
- addik r3,r3,-1 /* delay slot */
-
- bneid r3,1b
- addik r5,r5,1 /* delay slot */
-
- addik r3,r3,-1 /* for break on len */
-2:
- rsubk r3,r3,r6
-3:
- rtsd r15,8
- nop
- .size __strnlen_user, . - __strnlen_user
-
- .section .fixup,"ax"
-4:
- brid 3b
- addk r3,r0,r0
-
- .section __ex_table,"a"
- .word 1b,4b
-
/* Loop unrolling for __copy_tofrom_user */
#define COPY(offset) \
1: lwi r4 , r6, 0x0000 + offset; \
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 6dfb27d531dd..24e374266fdc 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -9,6 +9,8 @@ config MIPS
select ARCH_HAS_KCOV
select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE if !EVA
select ARCH_HAS_PTE_SPECIAL if !(32BIT && CPU_HAS_RIXI)
+ select ARCH_HAS_STRNCPY_FROM_USER
+ select ARCH_HAS_STRNLEN_USER
select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST
select ARCH_HAS_UBSAN_SANITIZE_ALL
select ARCH_HAS_GCOV_PROFILE_ALL
diff --git a/arch/nds32/Kconfig b/arch/nds32/Kconfig
index 62313902d75d..9c9f3877abf9 100644
--- a/arch/nds32/Kconfig
+++ b/arch/nds32/Kconfig
@@ -26,8 +26,6 @@ config NDS32
select GENERIC_LIB_LSHRDI3
select GENERIC_LIB_MULDI3
select GENERIC_LIB_UCMPDI2
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_TRACEHOOK
diff --git a/arch/nios2/Kconfig b/arch/nios2/Kconfig
index c24955c81c92..3efe5533ea1c 100644
--- a/arch/nios2/Kconfig
+++ b/arch/nios2/Kconfig
@@ -13,8 +13,6 @@ config NIOS2
select GENERIC_CPU_DEVICES
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
select IRQ_DOMAIN
diff --git a/arch/openrisc/Kconfig b/arch/openrisc/Kconfig
index 591acc5990dc..50035a9816c8 100644
--- a/arch/openrisc/Kconfig
+++ b/arch/openrisc/Kconfig
@@ -25,8 +25,6 @@ config OPENRISC
select HAVE_UID16
select GENERIC_ATOMIC64
select GENERIC_CLOCKEVENTS_BROADCAST
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select GENERIC_SMP_IDLE_THREAD
select MODULES_USE_ELF_RELA
select HAVE_DEBUG_STACKOVERFLOW
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig
index 4f8c1fbf8f2f..95d4bbf4e455 100644
--- a/arch/parisc/Kconfig
+++ b/arch/parisc/Kconfig
@@ -10,6 +10,7 @@ config PARISC
select ARCH_HAS_ELF_RANDOMIZE
select ARCH_HAS_STRICT_KERNEL_RWX
select ARCH_HAS_UBSAN_SANITIZE_ALL
+ select ARCH_HAS_STRNLEN_USER
select ARCH_NO_SG_CHAIN
select ARCH_SUPPORTS_HUGETLBFS if PA20
select ARCH_SUPPORTS_MEMORY_FAILURE
@@ -33,7 +34,6 @@ config PARISC
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CPU_DEVICES
- select GENERIC_STRNCPY_FROM_USER
select GENERIC_LIB_DEVMEM_IS_ALLOWED
select SYSCTL_ARCH_UNALIGN_ALLOW
select SYSCTL_EXCEPTION_TRACE
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 663766fbf505..678a0acbad7b 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -183,8 +183,6 @@ config PPC
select GENERIC_IRQ_SHOW_LEVEL
select GENERIC_PCI_IOMAP if PCI
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_VDSO_TIME_NS
select HAVE_ARCH_AUDITSYSCALL
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig
index 4f7b70ae7c31..1452584f83be 100644
--- a/arch/riscv/Kconfig
+++ b/arch/riscv/Kconfig
@@ -56,8 +56,6 @@ 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_TIME_VSYSCALL if MMU && 64BIT
select HANDLE_DOMAIN_IRQ
select HAVE_ARCH_AUDITSYSCALL
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h
index 2316f2440881..9ed9aa37e836 100644
--- a/arch/s390/include/asm/uaccess.h
+++ b/arch/s390/include/asm/uaccess.h
@@ -233,23 +233,9 @@ raw_copy_in_user(void __user *to, const void __user *from, unsigned long n);
/*
* Copy a null terminated string from userspace.
*/
+long __must_check strncpy_from_user(char *dst, const char __user *src, long count);
-long __strncpy_from_user(char *dst, const char __user *src, long count);
-
-static inline long __must_check
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
- might_fault();
- return __strncpy_from_user(dst, src, count);
-}
-
-unsigned long __must_check __strnlen_user(const char __user *src, unsigned long count);
-
-static inline unsigned long strnlen_user(const char __user *src, unsigned long n)
-{
- might_fault();
- return __strnlen_user(src, n);
-}
+long __must_check strnlen_user(const char __user *src, long count);
/*
* Zero Userspace
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
index 7ec8b1fa0f08..94ca99bde59d 100644
--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -338,55 +338,3 @@ unsigned long __clear_user(void __user *to, unsigned long size)
return clear_user_xc(to, size);
}
EXPORT_SYMBOL(__clear_user);
-
-static inline unsigned long strnlen_user_srst(const char __user *src,
- unsigned long size)
-{
- unsigned long tmp1, tmp2;
-
- asm volatile(
- " lghi 0,0\n"
- " la %2,0(%1)\n"
- " la %3,0(%0,%1)\n"
- " slgr %0,%0\n"
- " sacf 256\n"
- "0: srst %3,%2\n"
- " jo 0b\n"
- " la %0,1(%3)\n" /* strnlen_user results includes \0 */
- " slgr %0,%1\n"
- "1: sacf 768\n"
- EX_TABLE(0b,1b)
- : "+a" (size), "+a" (src), "=a" (tmp1), "=a" (tmp2)
- :
- : "cc", "memory", "0");
- return size;
-}
-
-unsigned long __strnlen_user(const char __user *src, unsigned long size)
-{
- if (unlikely(!size))
- return 0;
- return strnlen_user_srst(src, size);
-}
-EXPORT_SYMBOL(__strnlen_user);
-
-long __strncpy_from_user(char *dst, const char __user *src, long size)
-{
- size_t done, len, offset, len_str;
-
- if (unlikely(size <= 0))
- return 0;
- done = 0;
- do {
- offset = (size_t)src & (L1_CACHE_BYTES - 1);
- len = min(size - done, L1_CACHE_BYTES - offset);
- if (copy_from_user(dst, src, len))
- return -EFAULT;
- len_str = strnlen(dst, len);
- done += len_str;
- src += len_str;
- dst += len_str;
- } while ((len_str == len) && (done < size));
- return done;
-}
-EXPORT_SYMBOL(__strncpy_from_user);
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index b683b69a4556..f37280e805ea 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -22,8 +22,6 @@ config SUPERH
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP if PCI
select GENERIC_SCHED_CLOCK
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select GENERIC_SMP_IDLE_THREAD
select GUP_GET_PTE_LOW_HIGH if X2TLB
select HAVE_ARCH_AUDITSYSCALL
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index f0c0f955e169..fa650e4eadba 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -37,8 +37,6 @@ config SPARC
select HAVE_EBPF_JIT if SPARC64
select HAVE_DEBUG_BUGVERBOSE
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select MODULES_USE_ELF_RELA
select PCI_SYSCALL if PCI
select PCI_MSI_ARCH_FALLBACKS if PCI_MSI
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index 0561b73cfd9a..77e66d3719f6 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -7,6 +7,8 @@ config UML
default y
select ARCH_EPHEMERAL_INODES
select ARCH_HAS_KCOV
+ select ARCH_HAS_STRNCPY_FROM_USER
+ select ARCH_HAS_STRNLEN_USER
select ARCH_NO_PREEMPT
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_SECCOMP_FILTER
diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h
index fe66d659acad..191ef36dd543 100644
--- a/arch/um/include/asm/uaccess.h
+++ b/arch/um/include/asm/uaccess.h
@@ -23,16 +23,13 @@
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 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 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
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 45962aaf2b2c..1146b85d708b 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -145,8 +145,6 @@ config X86
select GENERIC_PENDING_IRQ if SMP
select GENERIC_PTDUMP
select GENERIC_SMP_IDLE_THREAD
- select GENERIC_STRNCPY_FROM_USER
- select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
select GENERIC_GETTIMEOFDAY
select GENERIC_VDSO_TIME_NS
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 3878880469d1..f02b8850b01b 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -7,6 +7,8 @@ config XTENSA
select ARCH_HAS_SYNC_DMA_FOR_CPU if MMU
select ARCH_HAS_SYNC_DMA_FOR_DEVICE if MMU
select ARCH_HAS_DMA_SET_UNCACHED if MMU
+ select ARCH_HAS_STRNCPY_FROM_USER if !KASAN
+ select ARCH_HAS_STRNLEN_USER
select ARCH_USE_MEMTEST
select ARCH_USE_QUEUED_RWLOCKS
select ARCH_USE_QUEUED_SPINLOCKS
@@ -20,7 +22,6 @@ config XTENSA
select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
- select GENERIC_STRNCPY_FROM_USER if KASAN
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KASAN if MMU && !XIP_KERNEL
diff --git a/arch/xtensa/include/asm/uaccess.h b/arch/xtensa/include/asm/uaccess.h
index 5c9fb8005aa8..75bd8fbf52ba 100644
--- a/arch/xtensa/include/asm/uaccess.h
+++ b/arch/xtensa/include/asm/uaccess.h
@@ -290,8 +290,7 @@ clear_user(void __user *addr, unsigned long size)
#define __clear_user __xtensa_clear_user
-#ifndef CONFIG_GENERIC_STRNCPY_FROM_USER
-
+#ifdef CONFIG_ARCH_HAS_STRNCPY_FROM_USER
extern long __strncpy_user(char *dst, const char __user *src, long count);
static inline long
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c
index 415fe7faa37f..d79edbb98d2a 100644
--- a/arch/xtensa/kernel/xtensa_ksyms.c
+++ b/arch/xtensa/kernel/xtensa_ksyms.c
@@ -43,7 +43,7 @@ EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memset);
EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memmove);
-#ifndef CONFIG_GENERIC_STRNCPY_FROM_USER
+#ifdef CONFIG_ARCH_HAS_STRNCPY_FROM_USER
EXPORT_SYMBOL(__strncpy_user);
#endif
EXPORT_SYMBOL(clear_page);
diff --git a/include/asm-generic/bitops/builtin-ffs.h b/include/asm-generic/bitops/builtin-ffs.h
index 1dacfdb4247e..7b129329046b 100644
--- a/include/asm-generic/bitops/builtin-ffs.h
+++ b/include/asm-generic/bitops/builtin-ffs.h
@@ -8,7 +8,7 @@
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * differs in spirit from ffz (man ffs).
*/
#define ffs(x) __builtin_ffs(x)
diff --git a/include/asm-generic/bitops/ffs.h b/include/asm-generic/bitops/ffs.h
index e81868b2c0f0..323fd5d6ae26 100644
--- a/include/asm-generic/bitops/ffs.h
+++ b/include/asm-generic/bitops/ffs.h
@@ -8,7 +8,7 @@
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
+ * differs in spirit from ffz (man ffs).
*/
static inline int ffs(int x)
{
diff --git a/include/asm-generic/bitops/non-atomic.h b/include/asm-generic/bitops/non-atomic.h
index 365377fb104b..078cc68be2f1 100644
--- a/include/asm-generic/bitops/non-atomic.h
+++ b/include/asm-generic/bitops/non-atomic.h
@@ -14,7 +14,7 @@
* may be that only one operation succeeds.
*/
static __always_inline void
-arch___set_bit(int nr, volatile unsigned long *addr)
+arch___set_bit(unsigned int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -24,7 +24,7 @@ arch___set_bit(int nr, volatile unsigned long *addr)
#define __set_bit arch___set_bit
static __always_inline void
-arch___clear_bit(int nr, volatile unsigned long *addr)
+arch___clear_bit(unsigned int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -43,7 +43,7 @@ arch___clear_bit(int nr, volatile unsigned long *addr)
* may be that only one operation succeeds.
*/
static __always_inline
-void arch___change_bit(int nr, volatile unsigned long *addr)
+void arch___change_bit(unsigned int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -62,7 +62,7 @@ void arch___change_bit(int nr, volatile unsigned long *addr)
* but actually fail. You must protect multiple accesses with a lock.
*/
static __always_inline int
-arch___test_and_set_bit(int nr, volatile unsigned long *addr)
+arch___test_and_set_bit(unsigned int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -83,7 +83,7 @@ arch___test_and_set_bit(int nr, volatile unsigned long *addr)
* but actually fail. You must protect multiple accesses with a lock.
*/
static __always_inline int
-arch___test_and_clear_bit(int nr, volatile unsigned long *addr)
+arch___test_and_clear_bit(unsigned int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -96,7 +96,7 @@ arch___test_and_clear_bit(int nr, volatile unsigned long *addr)
/* WARNING: non atomic and it can be reordered! */
static __always_inline int
-arch___test_and_change_bit(int nr, volatile unsigned long *addr)
+arch___test_and_change_bit(unsigned int nr, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(nr);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
@@ -113,7 +113,7 @@ arch___test_and_change_bit(int nr, volatile unsigned long *addr)
* @addr: Address to start counting from
*/
static __always_inline int
-arch_test_bit(int nr, const volatile unsigned long *addr)
+arch_test_bit(unsigned int nr, const volatile unsigned long *addr)
{
return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
}
diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h
index a0b2f270dddc..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))
@@ -244,50 +249,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;
- strncpy(dst, (const char __force *)src, count);
- for (tmp = dst; *tmp && count > 0; tmp++, count--)
- ;
- return (tmp - dst);
-}
-#endif
-
-static inline long
-strncpy_from_user(char *dst, const char __user *src, long count)
-{
- if (!access_ok(src, 1))
- return -EFAULT;
- return __strncpy_from_user(dst, src, count);
-}
-
-/*
- * Return the size of a string (including the ending 0)
- *
- * Return 0 on exception, a value greater than N if too long
- */
-#ifndef __strnlen_user
-#define __strnlen_user(s, n) (strnlen((s), (n)) + 1)
-#endif
-
-/*
- * 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_user(src, n);
-}
-
-/*
* Zero Userspace
*/
#ifndef __clear_user
@@ -311,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 */
diff --git a/lib/Kconfig b/lib/Kconfig
index 5c9c0687f76d..5e7165e6a346 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -50,12 +50,18 @@ config HAVE_ARCH_BITREVERSE
This option enables the use of hardware bit-reversal instructions on
architectures which support such operations.
-config GENERIC_STRNCPY_FROM_USER
+config ARCH_HAS_STRNCPY_FROM_USER
bool
-config GENERIC_STRNLEN_USER
+config ARCH_HAS_STRNLEN_USER
bool
+config GENERIC_STRNCPY_FROM_USER
+ def_bool !ARCH_HAS_STRNCPY_FROM_USER
+
+config GENERIC_STRNLEN_USER
+ def_bool !ARCH_HAS_STRNLEN_USER
+
config GENERIC_NET_UTILS
bool