lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-Id: <20250107-arm-generic-entry-v3-30-4e5f3c15db2d@linaro.org>
Date: Tue, 07 Jan 2025 10:41:46 +0100
From: Linus Walleij <linus.walleij@...aro.org>
To: Dmitry Vyukov <dvyukov@...gle.com>, Oleg Nesterov <oleg@...hat.com>, 
 Russell King <linux@...linux.org.uk>, Kees Cook <kees@...nel.org>, 
 Andy Lutomirski <luto@...capital.net>, Will Drewry <wad@...omium.org>, 
 Frederic Weisbecker <frederic@...nel.org>, 
 "Paul E. McKenney" <paulmck@...nel.org>, 
 Jinjie Ruan <ruanjinjie@...wei.com>, Arnd Bergmann <arnd@...db.de>, 
 Ard Biesheuvel <ardb@...nel.org>, Al Viro <viro@...iv.linux.org.uk>
Cc: linux-arm-kernel@...ts.infradead.org, linux-kernel@...r.kernel.org, 
 Linus Walleij <linus.walleij@...aro.org>
Subject: [PATCH RFC v3 30/30] RFC: ARM: entry: Block IRQs in early IRQ
 context

When dabt, pabt or und exceptions occur on ARM, ordinary
interrupts (IRQs) can still happen. This isn't nice for the
kernels context tracker, which expect (when using generic
entry at least) that any nested IRQs happens
between irqentry_enter() and irqentry_exit(), else it
thinks something is fishy.

This workaround blocks interrupts in the pabt, dabt and
und exception paths until after context has been established
with irqentry_enter() and before it is exited with
irqentry_exit().

This seems like far from perfect: it seems an interrupt
could still occur right before the first disable_irq_notrace
or right after the userspace registers are restored in
ret_from_exception. I would like to know if there is some
way to set up these exceptions to inherently block IRQs
when handled, until we explicitly allow them between
irqentry_enter() and irqentry_exit() or if this is simply
the best we can do on ARM for these exceptions to make the
context tracker happy.

Signed-off-by: Linus Walleij <linus.walleij@...aro.org>
---
 arch/arm/kernel/entry-armv.S |  7 ++-----
 arch/arm/kernel/entry.c      | 18 ++++++++++++++++++
 2 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index ae2f952beea7611f0abc7bd299fc944335a21219..10f59b2864a43dc4e1b141513f39eb9404ae9fd0 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -389,6 +389,7 @@ ENDPROC(__fiq_abt)
 
 	.align	5
 __dabt_usr:
+	disable_irq_notrace
 	usr_entry uaccess=0
 	kuser_cmpxchg_check
 	mov	r2, sp
@@ -416,11 +417,6 @@ ENDPROC(__irq_usr)
 __und_usr:
 	usr_entry uaccess=0
 
-	@ IRQs must be enabled before attempting to read the instruction from
-	@ user space since that could cause a page/translation fault if the
-	@ page table was modified by another CPU.
-	enable_irq
-
 	tst	r5, #PSR_T_BIT			@ Thumb mode?
 	mov	r1, #2				@ set insn size to 2 for Thumb
 	bne	0f				@ handle as Thumb undef exception
@@ -438,6 +434,7 @@ ENDPROC(__und_usr)
 
 	.align	5
 __pabt_usr:
+	disable_irq_notrace
 	usr_entry
 	mov	r2, sp				@ regs
 	pabt_helper
diff --git a/arch/arm/kernel/entry.c b/arch/arm/kernel/entry.c
index 10714dda5753684c7a2b8960562748525de774a8..852e03fac6ce8956415e464a69d41328593d2cc6 100644
--- a/arch/arm/kernel/entry.c
+++ b/arch/arm/kernel/entry.c
@@ -16,8 +16,18 @@ noinstr asmlinkage void arm_und_handler(struct pt_regs *regs)
 {
 	irqentry_state_t state = irqentry_enter(regs);
 
+	/*
+	 * IRQs must be enabled before attempting to read the instruction from
+	 * user space since that could cause a page/translation fault if the
+	 * page table was modified by another CPU.
+	 */
+
+	local_irq_enable();
+
 	do_undefinstr(regs);
 
+	local_irq_disable();
+
 	irqentry_exit(regs, state);
 }
 
@@ -25,8 +35,12 @@ noinstr asmlinkage void arm_dabt_handler(unsigned long addr, unsigned int fsr, s
 {
 	irqentry_state_t state = irqentry_enter(regs);
 
+	local_irq_enable();
+
 	do_DataAbort(addr, fsr, regs);
 
+	local_irq_disable();
+
 	irqentry_exit(regs, state);
 }
 
@@ -34,8 +48,12 @@ noinstr asmlinkage void arm_pabt_handler(unsigned long addr, unsigned int ifsr,
 {
 	irqentry_state_t state = irqentry_enter(regs);
 
+	local_irq_enable();
+
 	do_PrefetchAbort(addr, ifsr, regs);
 
+	local_irq_disable();
+
 	irqentry_exit(regs, state);
 }
 

-- 
2.47.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ