Skip to content

Commit f938723

Browse files
jplexerclaude
andcommitted
fw/kernel: classify MemManage stacking faults as stack overflows
mem_manage_handler_c() only detects a stack overflow by checking whether MMFAR points into a stack guard region, gated on MMARVALID. A stacking fault (MSTKERR) -- exception entry pushing the frame after SP already overflowed into the guard -- never writes MMFAR, so it took the generic path and fault_handler_dump() dereferenced stacked_args inside the NoAccess guard region. That second fault escalated to a HardFault and rebooted the whole watch, so an app overflowing its stack on every launch looped the watch into the bootloader's PRF fallback instead of just being killed. Treat MSTKERR as a stack overflow directly. The stack overflow path already avoids reading the stacked frame when MSTKERR is set. Fixes FIRM-3949 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Signed-off-by: Joshua Jun <lets@throw.rocks>
1 parent b452498 commit f938723

1 file changed

Lines changed: 8 additions & 0 deletions

File tree

src/fw/kernel/fault_handling.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,14 @@ static void mem_manage_handler_c(unsigned int* stacked_args, unsigned int lr) {
351351
}
352352
}
353353
}
354+
// A stacking fault (MSTKERR) never writes MMFAR, so the guard-region check above cannot see
355+
// it. Exception-entry stacking only faults when SP has already overflowed into a guard region,
356+
// so classify it as a stack overflow. Without this we'd take the generic path below and fault
357+
// again dereferencing stacked_args inside the NoAccess guard, escalating an app stack overflow
358+
// into a HardFault reboot.
359+
if (mmfsr & (1 << 4) /* MSTKERR */) {
360+
stack_overflow = true;
361+
}
354362

355363
// If it's a stack overflow, backup the stack so that attempt_handle_hardware_fault() can jam in
356364
// our landing zone to return to

0 commit comments

Comments
 (0)