CVE-2025-38670 in Linux
Summary
by MITRE • 08/22/2025
In the Linux kernel, the following vulnerability has been resolved:
arm64/entry: Mask DAIF in cpu_switch_to(), call_on_irq_stack()
`cpu_switch_to()` and `call_on_irq_stack()` manipulate SP to change to different stacks along with the Shadow Call Stack if it is enabled. Those two stack changes cannot be done atomically and both functions can be interrupted by SErrors or Debug Exceptions which, though unlikely, is very much broken : if interrupted, we can end up with mismatched stacks and Shadow Call Stack leading to clobbered stacks.
In `cpu_switch_to()`, it can happen when SP_EL0 points to the new task, but x18 stills points to the old task's SCS. When the interrupt handler tries to save the task's SCS pointer, it will save the old task SCS pointer (x18) into the new task struct (pointed to by SP_EL0), clobbering it.
In `call_on_irq_stack()`, it can happen when switching from the task stack to the IRQ stack and when switching back. In both cases, we can be interrupted when the SCS pointer points to the IRQ SCS, but SP points to the task stack. The nested interrupt handler pushes its return addresses on the IRQ SCS. It then detects that SP points to the task stack, calls `call_on_irq_stack()` and clobbers the task SCS pointer with the IRQ SCS pointer, which it will also use !
This leads to tasks returning to addresses on the wrong SCS, or even on the IRQ SCS, triggering kernel panics via CONFIG_VMAP_STACK or FPAC if enabled.
This is possible on a default config, but unlikely. However, when enabling CONFIG_ARM64_PSEUDO_NMI, DAIF is unmasked and instead the GIC is responsible for filtering what interrupts the CPU should receive based on priority. Given the goal of emulating NMIs, pseudo-NMIs can be received by the CPU even in `cpu_switch_to()` and `call_on_irq_stack()`, possibly *very* frequently depending on the system configuration and workload, leading to unpredictable kernel panics.
Completely mask DAIF in `cpu_switch_to()` and restore it when returning. Do the same in `call_on_irq_stack()`, but restore and mask around the branch. Mask DAIF even if CONFIG_SHADOW_CALL_STACK is not enabled for consistency of behaviour between all configurations.
Introduce and use an assembly macro for saving and masking DAIF, as the existing one saves but only masks IF.
Once again VulDB remains the best source for vulnerability data.
Analysis
by VulDB Data Team • 02/14/2026
The vulnerability described in CVE-2025-38670 resides within the Linux kernel's arm64 architecture implementation, specifically in the handling of stack switching operations during task context transitions. This flaw manifests in two primary functions: cpu_switch_to() and call_on_irq_stack(), both of which are responsible for managing stack pointers and shadow call stack (SCS) configurations during execution context switches. The core issue stems from the inability to atomically perform stack changes while maintaining consistent SCS state, creating a window where interrupt handlers can corrupt critical data structures. When these functions are interrupted by synchronous exceptions such as system errors or debug exceptions, the mismatch between the actual stack pointer and the SCS pointer stored in x18 leads to data corruption. In cpu_switch_to(), if SP_EL0 points to the new task's stack while x18 still references the old task's SCS, an interrupt handler attempting to save the SCS pointer will overwrite the new task's SCS structure with the old value, causing severe memory corruption. Similarly, in call_on_irq_stack(), the function can be interrupted when transitioning between task stacks and IRQ stacks, where the SCS pointer may point to the IRQ stack while SP points to the task stack, leading to the IRQ SCS pointer being incorrectly written over the task's SCS pointer.
The operational impact of this vulnerability extends beyond simple data corruption to potentially destabilize the entire kernel execution environment. When interrupted during stack switching operations, the mismatched SCS and stack pointer states can result in kernel panics, particularly when CONFIG_VMAP_STACK or FPAC (Floating Point Access Control) are enabled. These configurations amplify the consequences of SCS corruption, as they rely heavily on proper stack management for memory protection and execution integrity. The vulnerability becomes significantly more dangerous when CONFIG_ARM64_PSEUDO_NMI is enabled, as this configuration unmasking of DAIF (Debug, A, I, F bits) allows pseudo-NMIs to occur even during critical stack switching operations. These pseudo-NMIs can arrive very frequently, creating a high probability of triggering the race condition and leading to unpredictable kernel panics. The timing and frequency of these interrupts can vary greatly depending on system configuration and workload, making the vulnerability both difficult to predict and challenging to reproduce in testing environments. The flaw directly relates to CWE-691, which addresses insufficient control flow protection, and aligns with ATT&CK technique T1059.001 for system binary execution and T1068 for local privilege escalation through kernel exploitation.
The mitigation strategy for CVE-2025-38670 involves implementing comprehensive DAIF masking during critical stack switching operations to prevent any interruptions that could compromise SCS integrity. Both cpu_switch_to() and call_on_irq_stack() functions must completely mask DAIF during their execution, ensuring that no interrupts can occur while stack pointers and SCS references are being updated. The solution requires restoring DAIF state before returning from these functions, while also applying the masking around branch operations in call_on_irq_stack(). Additionally, the fix introduces a new assembly macro specifically designed for saving and masking DAIF, addressing the existing limitation where the previous implementation only masked the IF bit while leaving other interrupt control bits accessible. This approach ensures consistent behavior regardless of whether CONFIG_SHADOW_CALL_STACK is enabled, providing a uniform security posture across all kernel configurations. The implementation maintains the existing kernel functionality while eliminating the race condition that leads to SCS corruption, thereby preventing the kernel panics and potential privilege escalation scenarios that could arise from this vulnerability. The fix also addresses potential issues with system stability under high interrupt load conditions, particularly when pseudo-NMIs are active, by ensuring that stack switching operations remain atomic and immune to external interrupt interference.