Skip to content

Commit 3308a2c

Browse files
keesAlex Shi
authored andcommitted
arm64/uaccess: Enable hardened usercopy
Enables CONFIG_HARDENED_USERCOPY checks on arm64. As done by KASAN in -next, renames the low-level functions to __arch_copy_*_user() so a static inline can do additional work before the copy. Signed-off-by: Kees Cook <keescook@chromium.org> (cherry picked from commit faf5b63e294151d6ac24ca6906d6f221bd3496cd) Signed-off-by: Alex Shi <alex.shi@linaro.org>
1 parent 49f10dd commit 3308a2c

5 files changed

Lines changed: 29 additions & 13 deletions

File tree

arch/arm64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ config ARM64
4949
select HAVE_ALIGNED_STRUCT_PAGE if SLUB
5050
select HAVE_ARCH_AUDITSYSCALL
5151
select HAVE_ARCH_BITREVERSE
52+
select HAVE_ARCH_HARDENED_USERCOPY
5253
select HAVE_ARCH_HUGE_VMAP
5354
select HAVE_ARCH_JUMP_LABEL
5455
select HAVE_ARCH_KASAN if SPARSEMEM_VMEMMAP && !(ARM64_16K_PAGES && ARM64_VA_BITS_48)

arch/arm64/include/asm/uaccess.h

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -269,24 +269,39 @@ do { \
269269
-EFAULT; \
270270
})
271271

272-
extern unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n);
273-
extern unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n);
272+
extern unsigned long __must_check __arch_copy_from_user(void *to, const void __user *from, unsigned long n);
273+
extern unsigned long __must_check __arch_copy_to_user(void __user *to, const void *from, unsigned long n);
274274
extern unsigned long __must_check __copy_in_user(void __user *to, const void __user *from, unsigned long n);
275275
extern unsigned long __must_check __clear_user(void __user *addr, unsigned long n);
276276

277+
static inline unsigned long __must_check __copy_from_user(void *to, const void __user *from, unsigned long n)
278+
{
279+
check_object_size(to, n, false);
280+
return __arch_copy_from_user(to, from, n);
281+
}
282+
283+
static inline unsigned long __must_check __copy_to_user(void __user *to, const void *from, unsigned long n)
284+
{
285+
check_object_size(from, n, true);
286+
return __arch_copy_to_user(to, from, n);
287+
}
288+
277289
static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n)
278290
{
279-
if (access_ok(VERIFY_READ, from, n))
280-
n = __copy_from_user(to, from, n);
281-
else /* security hole - plug it */
291+
if (access_ok(VERIFY_READ, from, n)) {
292+
check_object_size(to, n, false);
293+
n = __arch_copy_from_user(to, from, n);
294+
} else /* security hole - plug it */
282295
memset(to, 0, n);
283296
return n;
284297
}
285298

286299
static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n)
287300
{
288-
if (access_ok(VERIFY_WRITE, to, n))
289-
n = __copy_to_user(to, from, n);
301+
if (access_ok(VERIFY_WRITE, to, n)) {
302+
check_object_size(from, n, true);
303+
n = __arch_copy_to_user(to, from, n);
304+
}
290305
return n;
291306
}
292307

arch/arm64/kernel/arm64ksyms.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@ EXPORT_SYMBOL(copy_page);
3333
EXPORT_SYMBOL(clear_page);
3434

3535
/* user mem (segment) */
36-
EXPORT_SYMBOL(__copy_from_user);
37-
EXPORT_SYMBOL(__copy_to_user);
36+
EXPORT_SYMBOL(__arch_copy_from_user);
37+
EXPORT_SYMBOL(__arch_copy_to_user);
3838
EXPORT_SYMBOL(__clear_user);
3939
EXPORT_SYMBOL(__copy_in_user);
4040

arch/arm64/lib/copy_from_user.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
.endm
6767

6868
end .req x5
69-
ENTRY(__copy_from_user)
69+
ENTRY(__arch_copy_from_user)
7070
ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
7171
CONFIG_ARM64_PAN)
7272
add end, x0, x2
@@ -75,7 +75,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
7575
CONFIG_ARM64_PAN)
7676
mov x0, #0 // Nothing to copy
7777
ret
78-
ENDPROC(__copy_from_user)
78+
ENDPROC(__arch_copy_from_user)
7979

8080
.section .fixup,"ax"
8181
.align 2

arch/arm64/lib/copy_to_user.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
.endm
6666

6767
end .req x5
68-
ENTRY(__copy_to_user)
68+
ENTRY(__arch_copy_to_user)
6969
ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(0)), ARM64_ALT_PAN_NOT_UAO, \
7070
CONFIG_ARM64_PAN)
7171
add end, x0, x2
@@ -74,7 +74,7 @@ ALTERNATIVE("nop", __stringify(SET_PSTATE_PAN(1)), ARM64_ALT_PAN_NOT_UAO, \
7474
CONFIG_ARM64_PAN)
7575
mov x0, #0
7676
ret
77-
ENDPROC(__copy_to_user)
77+
ENDPROC(__arch_copy_to_user)
7878

7979
.section .fixup,"ax"
8080
.align 2

0 commit comments

Comments
 (0)