summaryrefslogtreecommitdiff
path: root/arch/um
diff options
context:
space:
mode:
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