[PATCH] ARM: mm: Disregard user space addresses in BUG() address check
Ard Biesheuvel
ardb+git at google.com
Wed Jan 17 07:07:34 PST 2024
From: Ard Biesheuvel <ardb at kernel.org>
is_valid_bugaddr() dereferences the faulting PC to fetch the instruction
that triggered the fault, to decide whether it is a BRK instruction used
to force an exception. This is used by the BUG() infrastructure to keep
the handling logic (which should never execute) separate from the code
that normally runs.
This dereference may attempt to access user memory if the faulting PC
happens to contain a user address. One way this might happen is when
the kernel is tricked into executing from user space while PAN
protections (Privileged Access Never) are in effect: the instruction
fetch will trigger a prefetch abort, the handling of which involves a
check whether the instruction that caused it is a BRK, requiring a
load from the same address. This load is privileged too, and so it will
trigger another exception, which we fail to recover from.
Given that BRK instructions tied to BUG() handling can only appear in
kernel code, let's check first that the PC actually points into kernel
memory.
Cc: Kees Cook <keescook at chromium.org>
Cc: Russell King <rmk+kernel at armlinux.org.uk>
Cc: Mark Brown <broonie at kernel.org>
Cc: Zhen Lei <thunder.leizhen at huawei.com>
Cc: Linus Walleij <linus.walleij at linaro.org>
Link: https://lkml.kernel.org/r/202401111544.18EBB6AA%40keescook
Signed-off-by: Ard Biesheuvel <ardb at kernel.org>
---
arch/arm/kernel/traps.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 3bad79db5d6e..f342bd6b2a5d 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -402,6 +402,9 @@ int is_valid_bugaddr(unsigned long pc)
u32 insn = __opcode_to_mem_arm(BUG_INSTR_VALUE);
#endif
+ if (pc < TASK_SIZE)
+ return 0;
+
if (get_kernel_nofault(bkpt, (void *)pc))
return 0;
--
2.43.0.381.gb435a96ce8-goog
More information about the linux-arm-kernel
mailing list