* [PATCH] parisc: Avoid crash due to unaligned access in unwinder
@ 2025-11-03 22:11 deller
2025-11-03 22:42 ` Guenter Roeck
0 siblings, 1 reply; 2+ messages in thread
From: deller @ 2025-11-03 22:11 UTC (permalink / raw)
To: linux-parisc; +Cc: Guenter Roeck
From: Helge Deller <deller@gmx.de>
Guenter Roeck reported this kernel crash on his emulated B160L machine:
Starting network: udhcpc: started, v1.36.1
Backtrace:
[<104320d4>] unwind_once+0x1c/0x5c
[<10434a00>] walk_stackframe.isra.0+0x74/0xb8
[<10434a6c>] arch_stack_walk+0x28/0x38
[<104e5efc>] stack_trace_save+0x48/0x5c
[<105d1bdc>] set_track_prepare+0x44/0x6c
[<105d9c80>] ___slab_alloc+0xfc4/0x1024
[<105d9d38>] __slab_alloc.isra.0+0x58/0x90
[<105dc80c>] kmem_cache_alloc_noprof+0x2ac/0x4a0
[<105b8e54>] __anon_vma_prepare+0x60/0x280
[<105a823c>] __vmf_anon_prepare+0x68/0x94
[<105a8b34>] do_wp_page+0x8cc/0xf10
[<105aad88>] handle_mm_fault+0x6c0/0xf08
[<10425568>] do_page_fault+0x110/0x440
[<10427938>] handle_interruption+0x184/0x748
[<11178398>] schedule+0x4c/0x190
BUG: spinlock recursion on CPU#0, ifconfig/2420
lock: terminate_lock.2+0x0/0x1c, .magic: dead4ead, .owner: ifconfig/2420, .owner_cpu: 0
While creating the stack trace, the unwinder uses the stack pointer to guess
the previous frame to read the previous stack pointer from memory. The crash
happens, because the unwinder tries to read from unaligned memory and as such
triggers the unalignment trap handler which then leads to the spinlock
recursion and finally to a deadlock.
Fix it by checking the alignment before accessing the memory.
Reported-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Helge Deller <deller@gmx.de>
Cc: <stable@vger.kernel.org> # v6.12+
---
arch/parisc/kernel/unwind.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/arch/parisc/kernel/unwind.c b/arch/parisc/kernel/unwind.c
index f7e0fee5ee55..7ac88ff13d3c 100644
--- a/arch/parisc/kernel/unwind.c
+++ b/arch/parisc/kernel/unwind.c
@@ -35,6 +35,8 @@
#define KERNEL_START (KERNEL_BINARY_TEXT_START)
+#define ALIGNMENT_OK(ptr, type) (((ptr) & (sizeof(type) - 1)) == 0)
+
extern struct unwind_table_entry __start___unwind[];
extern struct unwind_table_entry __stop___unwind[];
@@ -257,12 +259,15 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
if (pc_is_kernel_fn(pc, _switch_to) ||
pc == (unsigned long)&_switch_to_ret) {
info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
- info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
+ if (ALIGNMENT_OK(info->prev_sp, long))
+ info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
+ else
+ info->prev_ip = info->prev_sp = 0;
return 1;
}
#ifdef CONFIG_IRQSTACKS
- if (pc == (unsigned long)&_call_on_stack) {
+ if (pc == (unsigned long)&_call_on_stack && ALIGNMENT_OK(info->sp, long)) {
info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
return 1;
@@ -370,8 +375,10 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
info->prev_sp = info->sp - frame_size;
if (e->Millicode)
info->rp = info->r31;
- else if (rpoffset)
+ else if (rpoffset && ALIGNMENT_OK(info->prev_sp, long))
info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
+ else
+ info->rp = 0;
info->prev_ip = info->rp;
info->rp = 0;
}
--
2.51.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] parisc: Avoid crash due to unaligned access in unwinder
2025-11-03 22:11 [PATCH] parisc: Avoid crash due to unaligned access in unwinder deller
@ 2025-11-03 22:42 ` Guenter Roeck
0 siblings, 0 replies; 2+ messages in thread
From: Guenter Roeck @ 2025-11-03 22:42 UTC (permalink / raw)
To: deller; +Cc: linux-parisc
On Mon, Nov 03, 2025 at 11:11:10PM +0100, deller@kernel.org wrote:
> From: Helge Deller <deller@gmx.de>
>
> Guenter Roeck reported this kernel crash on his emulated B160L machine:
>
> Starting network: udhcpc: started, v1.36.1
> Backtrace:
> [<104320d4>] unwind_once+0x1c/0x5c
> [<10434a00>] walk_stackframe.isra.0+0x74/0xb8
> [<10434a6c>] arch_stack_walk+0x28/0x38
> [<104e5efc>] stack_trace_save+0x48/0x5c
> [<105d1bdc>] set_track_prepare+0x44/0x6c
> [<105d9c80>] ___slab_alloc+0xfc4/0x1024
> [<105d9d38>] __slab_alloc.isra.0+0x58/0x90
> [<105dc80c>] kmem_cache_alloc_noprof+0x2ac/0x4a0
> [<105b8e54>] __anon_vma_prepare+0x60/0x280
> [<105a823c>] __vmf_anon_prepare+0x68/0x94
> [<105a8b34>] do_wp_page+0x8cc/0xf10
> [<105aad88>] handle_mm_fault+0x6c0/0xf08
> [<10425568>] do_page_fault+0x110/0x440
> [<10427938>] handle_interruption+0x184/0x748
> [<11178398>] schedule+0x4c/0x190
> BUG: spinlock recursion on CPU#0, ifconfig/2420
> lock: terminate_lock.2+0x0/0x1c, .magic: dead4ead, .owner: ifconfig/2420, .owner_cpu: 0
>
> While creating the stack trace, the unwinder uses the stack pointer to guess
> the previous frame to read the previous stack pointer from memory. The crash
> happens, because the unwinder tries to read from unaligned memory and as such
> triggers the unalignment trap handler which then leads to the spinlock
> recursion and finally to a deadlock.
>
> Fix it by checking the alignment before accessing the memory.
>
> Reported-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Helge Deller <deller@gmx.de>
> Cc: <stable@vger.kernel.org> # v6.12+
Tested-by: Guenter Roeck <linux@roeck-us.net>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-11-03 22:42 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-03 22:11 [PATCH] parisc: Avoid crash due to unaligned access in unwinder deller
2025-11-03 22:42 ` Guenter Roeck
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).