linux-uconsole/arch
Lexi Shao 3ceaa85c33 ARM: 9132/1: Fix __get_user_check failure with ARM KASAN images
commit df909df077 upstream.

ARM: kasan: Fix __get_user_check failure with kasan

In macro __get_user_check defined in arch/arm/include/asm/uaccess.h,
error code is store in register int __e(r0). When kasan is
enabled, assigning value to kernel address might trigger kasan check,
which unexpectedly overwrites r0 and causes undefined behavior on arm
kasan images.

One example is failure in do_futex and results in process soft lockup.
Log:
watchdog: BUG: soft lockup - CPU#0 stuck for 62946ms! [rs:main
Q:Reg:1151]
...
(__asan_store4) from (futex_wait_setup+0xf8/0x2b4)
(futex_wait_setup) from (futex_wait+0x138/0x394)
(futex_wait) from (do_futex+0x164/0xe40)
(do_futex) from (sys_futex_time32+0x178/0x230)
(sys_futex_time32) from (ret_fast_syscall+0x0/0x50)

The soft lockup happens in function futex_wait_setup. The reason is
function get_futex_value_locked always return EINVAL, thus pc jump
back to retry label and causes looping.

This line in function get_futex_value_locked
	ret = __get_user(*dest, from);
is expanded to
	*dest = (typeof(*(p))) __r2; ,
in macro __get_user_check. Writing to pointer dest triggers kasan check
and overwrites the return value of __get_user_x function.
The assembly code of get_futex_value_locked in kernel/futex.c:
...
c01f6dc8:       eb0b020e        bl      c04b7608 <__get_user_4>
// "x = (typeof(*(p))) __r2;" triggers kasan check and r0 is overwritten
c01f6dCc:       e1a00007        mov     r0, r7
c01f6dd0:       e1a05002        mov     r5, r2
c01f6dd4:       eb04f1e6        bl      c0333574 <__asan_store4>
c01f6dd8:       e5875000        str     r5, [r7]
// save ret value of __get_user(*dest, from), which is dest address now
c01f6ddc:       e1a05000        mov     r5, r0
...
// checking return value of __get_user failed
c01f6e00:       e3550000        cmp     r5, #0
...
c01f6e0c:       01a00005        moveq   r0, r5
// assign return value to EINVAL
c01f6e10:       13e0000d        mvnne   r0, #13

Return value is the destination address of get_user thus certainly
non-zero, so get_futex_value_locked always return EINVAL.

Fix it by using a tmp vairable to store the error code before the
assignment. This fix has no effects to non-kasan images thanks to compiler
optimization. It only affects cases that overwrite r0 due to kasan check.

This should fix bug discussed in Link:
[1] https://lore.kernel.org/linux-arm-kernel/0ef7c2a5-5d8b-c5e0-63fa-31693fd4495c@gmail.com/

Fixes: 421015713b ("ARM: 9017/2: Enable KASan for ARM")
Signed-off-by: Lexi Shao <shaolexi@huawei.com>
Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2021-11-02 19:48:17 +01:00
..
alpha alpha: Declare virt_to_phys and virt_to_bus parameter as pointer to volatile 2021-09-30 10:11:07 +02:00
arc ARC: export clear_user_page() for modules 2021-09-22 12:28:04 +02:00
arm ARM: 9132/1: Fix __get_user_check failure with ARM KASAN images 2021-11-02 19:48:17 +01:00
arm64 arm64/hugetlb: fix CMA gigantic page order for non-4K PAGE_SIZE 2021-10-20 11:44:58 +02:00
c6x
csky csky: Fixup regs.sr broken in ptrace 2021-10-20 11:44:58 +02:00
h8300 h8300: fix PREEMPTION build, TI_PRE_COUNT undefined 2021-02-17 11:02:28 +01:00
hexagon hexagon: use common DISCARDS macro 2021-07-20 16:05:53 +02:00
ia64 mm/page_alloc: fix memory map initialization for descending nodes 2021-07-25 14:36:18 +02:00
m68k m68k: Handle arrivals of multiple signals correctly 2021-10-17 10:43:32 +02:00
microblaze local64.h: make <asm/local64.h> mandatory 2021-01-12 20:18:16 +01:00
mips bpf, mips: Validate conditional branch offsets 2021-10-06 15:55:51 +02:00
nds32 nds32: fix up stack guard gap 2021-07-28 14:35:46 +02:00
nios2 NIOS2: irqflags: rename a redefined register name 2021-10-27 09:56:48 +02:00
openrisc openrisc: don't printk() unconditionally 2021-09-18 13:40:13 +02:00
parisc parisc: math-emu: Fix fall-through warnings 2021-10-27 09:56:46 +02:00
powerpc powerpc/idle: Don't corrupt back chain when going idle 2021-10-27 09:56:53 +02:00
riscv RISC-V: Include clone3() on rv32 2021-10-13 10:04:29 +02:00
s390 s390/pci: fix zpci_zdev_put() on reserve 2021-10-27 09:56:56 +02:00
sh sched/core: Initialize the idle task with preemption disabled 2021-07-14 16:55:50 +02:00
sparc sparc64: fix pci_iounmap() when CONFIG_PCI is not set 2021-10-09 14:40:56 +02:00
um um: virtio_uml: fix memory leak on init failures 2021-09-26 14:08:57 +02:00
x86 perf/x86/msr: Add Sapphire Rapids CPU support 2021-10-27 09:56:55 +02:00
xtensa xtensa: xtfpga: Try software restart before simulating CPU reset 2021-10-27 09:56:47 +02:00
.gitignore
Kconfig fanotify: Fix sys_fanotify_mark() on native x86-32 2021-01-17 14:16:59 +01:00