fix(core): reset primask in emergency rescue
What changed, and why it matters
This commit fixes a low-level crash-recovery bug in Trezor hardware wallets. If the device crashed while interrupts were temporarily disabled (a common protective state during sensitive operations), the emergency rescue code could fail to re-enable normal interrupts before showing the Red Screen of Death (RSOD). The fix adds one line to re-enable interrupts so the recovery screen works reliably. There is no direct evidence this is exploitable as an attack; it is primarily a reliability/resilience fix.
Treat as a routine firmware hardening fix. Include in normal release notes; no urgent security response required absent evidence of an exploit path. Review whether other fault/exception entry paths also need PRIMASK restoration.
Security signals we found
Crash-recovery path in embedded firmware
Interrupt state not fully restored on fault entry
RSOD (error screen) may fail to render after crash
Potential denial-of-availability if device cannot recover from fault
Evidence from the diff
In core/embed/sys/task/stm32/system.c, system_emergency_rescue_phase_2() already called __enable_fault_irq() after a crash. The patch adds __enable_irq() to also clear PRIMASK, restoring normal (non-fault) interrupts. Without this, if the crash occurred inside a critical section where irq_lock / PRIMASK was active, the rescue path could continue with interrupts disabled, preventing RSOD rendering/timers/etc. from functioning correctly. The change is defensive and improves fault recovery behavior.
Changed components
core/embed/sys/task/stm32/system.csystem_emergency_rescue_phase_2()Trezor Core firmware on STM32Inspect captured patch +2 / −0
diff --git a/core/embed/sys/task/stm32/system.c b/core/embed/sys/task/stm32/system.c
index 6e4b41db..526400a5 100644
--- a/core/embed/sys/task/stm32/system.c
+++ b/core/embed/sys/task/stm32/system.c
@@ -129,6 +129,8 @@ system_emergency_rescue_phase_2(uint32_t arg1, uint32_t arg2) {
// Now we can safely enable interrupts again
__enable_fault_irq();
+ // In case we crashed while irq_lock was active
+ __enable_irq();
#ifndef SECMON
// Ensure we are in thread mode.
Why this scored 41/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.