summaryrefslogtreecommitdiffstats
path: root/arch/um
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2021-09-02 00:13:02 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2021-09-02 00:13:02 +0200
commit4cdc4cc2ad35f92338497d53d3e8b7876cf2a51d (patch)
tree6d603bb48eeed47a4d37547c3a96c79800a2390f /arch/um
parentMerge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/a... (diff)
parentbitops/non-atomic: make @nr unsigned to avoid any DIV (diff)
downloadlinux-4cdc4cc2ad35f92338497d53d3e8b7876cf2a51d.tar.xz
linux-4cdc4cc2ad35f92338497d53d3e8b7876cf2a51d.zip
Merge tag 'asm-generic-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic
Pull asm-generic updates from Arnd Bergmann: "The main content for 5.15 is a series that cleans up the handling of strncpy_from_user() and strnlen_user(), removing a lot of slightly incorrect versions of these in favor of the lib/strn*.c helpers that implement these correctly and more efficiently. The only architectures that retain a private version now are mips, ia64, um and parisc. I had offered to convert those at all, but Thomas Bogendoerfer wanted to keep the mips version for the moment until he had a chance to do regression testing. The branch also contains two patches for bitops and for ffs()" * tag 'asm-generic-5.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arnd/asm-generic: bitops/non-atomic: make @nr unsigned to avoid any DIV asm-generic: ffs: Drop bogus reference to ffz location asm-generic: reverse GENERIC_{STRNCPY_FROM,STRNLEN}_USER symbols asm-generic: remove extra strn{cpy_from,len}_user declarations asm-generic: uaccess: remove inline strncpy_from_user/strnlen_user s390: use generic strncpy/strnlen from_user microblaze: use generic strncpy/strnlen from_user csky: use generic strncpy/strnlen from_user arc: use generic strncpy/strnlen from_user hexagon: use generic strncpy/strnlen from_user h8300: remove stale strncpy_from_user asm-generic/uaccess.h: remove __strncpy_from_user/__strnlen_user
Diffstat (limited to 'arch/um')
-rw-r--r--arch/um/Kconfig2
-rw-r--r--arch/um/include/asm/uaccess.h5
-rw-r--r--arch/um/kernel/skas/uaccess.c14
3 files changed, 13 insertions, 8 deletions
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