Commit bffe1baf authored by Yang Shi's avatar Yang Shi Committed by Catalin Marinas

arm64: kasan: instrument user memory access API

The upstream commit 1771c6e1
("x86/kasan: instrument user memory access API") added KASAN instrument to
x86 user memory access API, so added such instrument to ARM64 too.

Define __copy_to/from_user in C in order to add kasan_check_read/write call,
rename assembly implementation to __arch_copy_to/from_user.

Tested by test_kasan module.
Acked-by: default avatarAndrey Ryabinin <aryabinin@virtuozzo.com>
Reviewed-by: default avatarMark Rutland <mark.rutland@arm.com>
Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarYang Shi <yang.shi@linaro.org>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 4674fdb9
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
/* /*
* User space memory access functions * User space memory access functions
*/ */
#include <linux/kasan-checks.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/thread_info.h> #include <linux/thread_info.h>
...@@ -256,15 +257,29 @@ do { \ ...@@ -256,15 +257,29 @@ do { \
-EFAULT; \ -EFAULT; \
}) })
extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n); extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n); extern unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n);
extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n); extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n);
extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n); extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n)
{
kasan_check_write(to, n);
return __arch_copy_from_user(to, from, n);
}
static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
{
kasan_check_read(from, n);
return __arch_copy_to_user(to, from, n);
}
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
{ {
kasan_check_write(to, n);
if (access_ok(VERIFY_READ, from, n)) if (access_ok(VERIFY_READ, from, n))
n = __copy_from_user(to, from, n); n = __arch_copy_from_user(to, from, n);
else /* security hole - plug it */ else /* security hole - plug it */
memset(to, 0, n); memset(to, 0, n);
return n; return n;
...@@ -272,8 +287,10 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u ...@@ -272,8 +287,10 @@ static inline unsigned long __must_check copy_from_user(void *to, const void __u
static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
{ {
kasan_check_read(from, n);
if (access_ok(VERIFY_WRITE, to, n)) if (access_ok(VERIFY_WRITE, to, n))
n = __copy_to_user(to, from, n); n = __arch_copy_to_user(to, from, n);
return n; return n;
} }
......
...@@ -34,8 +34,8 @@ EXPORT_SYMBOL(copy_page); ...@@ -34,8 +34,8 @@ EXPORT_SYMBOL(copy_page);
EXPORT_SYMBOL(clear_page); EXPORT_SYMBOL(clear_page);
/* user mem (segment) */ /* user mem (segment) */
EXPORT_SYMBOL(__copy_from_user); EXPORT_SYMBOL(__arch_copy_from_user);
EXPORT_SYMBOL(__copy_to_user); EXPORT_SYMBOL(__arch_copy_to_user);
EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(__clear_user);
EXPORT_SYMBOL(__copy_in_user); EXPORT_SYMBOL(__copy_in_user);
......
...@@ -66,7 +66,7 @@ ...@@ -66,7 +66,7 @@
.endm .endm
end .req x5 end .req x5
ENTRY(__copy_from_user) ENTRY(__arch_copy_from_user)
ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN) CONFIG_ARM64_PAN)
add end, x0, x2 add end, x0, x2
...@@ -75,7 +75,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \ ...@@ -75,7 +75,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN) CONFIG_ARM64_PAN)
mov x0, #0 // Nothing to copy mov x0, #0 // Nothing to copy
ret ret
ENDPROC(__copy_from_user) ENDPROC(__arch_copy_from_user)
.section .fixup,"ax" .section .fixup,"ax"
.align 2 .align 2
......
...@@ -65,7 +65,7 @@ ...@@ -65,7 +65,7 @@
.endm .endm
end .req x5 end .req x5
ENTRY(__copy_to_user) ENTRY(__arch_copy_to_user)
ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN) CONFIG_ARM64_PAN)
add end, x0, x2 add end, x0, x2
...@@ -74,7 +74,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \ ...@@ -74,7 +74,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
CONFIG_ARM64_PAN) CONFIG_ARM64_PAN)
mov x0, #0 mov x0, #0
ret ret
ENDPROC(__copy_to_user) ENDPROC(__arch_copy_to_user)
.section .fixup,"ax" .section .fixup,"ax"
.align 2 .align 2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment