Skip to content

Instantly share code, notes, and snippets.

@Cr4sh
Created March 1, 2026 14:53
Show Gist options
  • Select an option

  • Save Cr4sh/ce20d2d5d10ab145a9b1daff4957c0bc to your computer and use it in GitHub Desktop.

Select an option

Save Cr4sh/ce20d2d5d10ab145a9b1daff4957c0bc to your computer and use it in GitHub Desktop.
Claude experiments: Intel S1200 SW SMI vulnerabilities discovery

Intel S1200 Motherboard - SMM SMI Handler Security Audit

Target: Intel S1200 Motherboard EFI Flash Image Tool: IDA Pro with efiXplorer plugin Date: 2026-03-01 Analyst: Claude (automated reverse engineering via IDA Pro MCP + idasql)


Table of Contents

  1. Executive Summary
  2. Methodology
  3. Flash Image Overview
  4. SMM Module Inventory
  5. SMI Handler Discovery
  6. Vulnerability Analysis
  7. Clean Handler Analysis
  8. Design Concerns
  9. Appendix A: Protocol GUID Reference
  10. Appendix B: SMRAM Validation Function Analysis

Executive Summary

This report documents a comprehensive audit of SMM (System Management Mode) SMI (System Management Interrupt) handlers in an Intel S1200 motherboard UEFI flash image. The analysis was conducted through automated reverse engineering using IDA Pro with efiXplorer plugin, leveraging both the ida-pro-mcp and idasql MCP servers for decompilation, disassembly, cross-reference analysis, and SQL-based bulk queries.

Key Findings

ID Severity Module Description
V1 CRITICAL SmiVariable (0xEF) Embedded pointers from NVS buffer not validated against SMRAM before dereference in commands 6 and 7
V2 CRITICAL SmiVariable (0xEF) Password verification function sub_1F29D8 validates wrong memory region after reading from user-controlled pointer
V3 MEDIUM SmiVariable (0xEF) Variable name pointer validated with only 2-byte check in SetVariable path; password pointer uses broken V2 path
V4 LOW SmiVariable (0xEF) Variable name string iteration precedes (broken) SMRAM validation in GetVariable path

The most impactful finding is the combination of V1 + V2: the SmiVariable handler (SW SMI# 0xEF) commands 6 and 7 allow an OS-level attacker to read up to 30 bytes from arbitrary physical addresses (including SMRAM) by crafting malicious pointer values in the ACPI NVS shared memory buffer. The SMRAM validation function (sub_1F3680) exists and is correctly implemented, but it is either not called for embedded pointers (V1) or called on the wrong memory region after the data has already been read (V2).

All remaining SW SMI handlers (SmmPlatform 0xF0/0xF1/0x9F, PowerMgmtSmm 0x27/0x28, TcgSmm, TrEESmm) were found to be clean - they either process only hardcoded values, operate on hardware registers directly, or read exclusively from protected UEFI variables.


Methodology

Tools and Approach

  1. IDA Pro + efiXplorer: Binary loaded with efiXplorer plugin for automatic UEFI module identification, GUID labeling, and protocol resolution
  2. ida-pro-mcp (mrexodia): Used for targeted operations - function decompilation, disassembly, cross-references, global variable reads, memory reads
  3. idasql (allthingsida): Used for bulk analysis - SQL queries across function tables, name tables, string tables to discover SMM modules and handler patterns
  4. Analysis flow:
    • Identified all SMM module entry points via idasql function name queries
    • Decompiled each entry point to find initialization functions
    • Decompiled initialization functions to identify dispatch protocol usage
    • Read 16-byte GUID values at protocol reference addresses to identify dispatch types
    • Mapped callback functions to their dispatch types and context values (SW SMI numbers, IO ports, SX states)
    • Decompiled all SW SMI handler callbacks for vulnerability analysis
    • Disassembled critical validation functions where decompiler output was incorrect

Vulnerability Classes Checked

  • Callout vulnerabilities: SMI handler calling code outside SMRAM via function pointers
  • TOCTOU (Time-of-check to time-of-use): Using pointers from shared memory without proper validation ordering
  • Confused deputy / Arbitrary read: Reading from attacker-controlled addresses within SMRAM
  • Arbitrary write: Writing to attacker-controlled addresses
  • CommBuffer/NVS validation: Missing or incomplete validation of shared memory pointers
  • Pointer injection: Embedded pointers within comm structures not validated against SMRAM
  • Integer overflow: In size/address calculations for buffer validation
  • Missing authentication: Operations without proper access control

Flash Image Overview

The Intel S1200 EFI flash image contains 3 redundant copies of each firmware volume. All analysis references the primary (first) copy of each module. The image contains approximately 30 SMM driver modules loaded into SMRAM during the DXE/SMM initialization phase.

SMM Infrastructure Modules

Module Address Role
PiSmmIpl 0x961600 SMM Initial Program Loader - loads SMM core
PiSmmCore 0x964990 SMM core dispatcher - manages handler registration
PiSmmCpuDxeSmm 0x96D9C0 CPU-specific SMM support (save state, entry point)
CpuIo2Smm 0x9762F0 CPU I/O protocol for SMM
SmmLockBox 0x97E320 Secure storage for sleep/resume data
SmmCommunicationBuffer 0x96A280 SMM communication buffer management
PiSmmCommunicationSmm 0x980360 SMM communication protocol

SMM Module Inventory

The following table lists all unique SMM driver modules discovered in the flash image:

# Module Name Primary Address GUID Suffix Registers Handlers
1 PchSmiDispatcher 0x56D0A0 F3B06B78 Yes - Root dispatcher
2 SmmPlatform 0xA26A60 03475173 Yes - SW, SX, PowerButton
3 SmiVariable 0x1F25C0 1D5839DD Yes - SW
4 PowerMgmtSmm 0x5535D0 A2907927 Yes - SW, IoTrap, SX
5 TcgSmm 0x629430 B95D4333 Yes - SW (dynamic)
6 TrEESmm 0x622470 ADBBC8B6 Yes - SW (dynamic)
7 PchInitSmm 0x584B60 5B37FC53 Yes - IoTrap, USB, SX
8 SaLateInitSmm 0x549460 2633DE85 Yes - IoTrap
9 SmmNmiButton 0x42F610 A9D8513C Yes - NMI/PowerButton
10 KbcEmulSMM 0xA8A2A0 AAB28A80 Yes - USB, Custom
11 HeciSmm 0x590290 B4D62061 Yes - Protocol-based
12 VariableSmm 0x2B89E0 8CE124A5 Yes - Root SMI
13 SmiFlashSigned 0x3F8680 462AA0C9 Yes - SmmCommunicate
14 VariableSmmRuntimeDxe 0x1EF600 0BC0045A Yes - SmmCommunicate
15 SmmFaultTolerantWriteDxe 0x293330 1C4FAE01 Yes - ProtocolNotify
16 FwBlockServiceSmm 0x2883B0 1866FC64 No - Service provider
17 PchSpiSmm 0x5812E0 C553AE2C No - SPI protocol
18 PchSmbusSmm 0x57F2B0 F89F9DDD No - SMBus protocol
19 SmmGenericIpmi 0x1985D0 17716E7A Likely - decompilation failed
20 SmmErrorLog 0xA432D8 6B839725 No - Error logging
21 PepBccdSmm 0xA292D0 EC6D8D3B No - Config reader
22 SmmAccess 0x53B2A0 AFE99BFB No - SMRAM access control
23 SmmControl 0x5749D0 F8F03F1C No - SMI generation
24 ReportStatusCodeRouterSmm 0x18F2E0 413900D4 No - Status code routing
25 StatusCodeHandlerSmm 0x1905C0 395FCBD0 No - Status code handler
26 PlatformStatusCodeHandlerSmm 0x1D1A80 A6EDB8A5 No - Platform status codes
27 SmiVariableInstallInt15Dxe 0x2FF2E0 3C3A9F65 No - DXE-side helper
28 BdatAccessHandler 0x5502D0 589F5B04 Separate analysis needed

SMI Handler Discovery

SW Dispatch Handlers

Protocol GUID: EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID = {18A3C6DC-5EEA-48C8-A1C1-B53389F98999}

SW SMI# Decimal Module Callback Function Registration Site Description
0xF0 240 SmmPlatform sub_A26BA4 sub_A273EC+0x226 Platform sleep preparation - PCI config save/restore
0xF1 241 SmmPlatform sub_A26ED0 sub_A273EC+0x24D Platform wake restoration - PCI config restore
0x9F 159 SmmPlatform sub_A27810 sub_A273EC+0x276 Stub handler (returns 0 immediately)
0xEF 239 SmiVariable sub_1F2EDC sub_1F28E8+0xBA UEFI Variable access SMI - complex multi-command handler
0x28 40 PowerMgmtSmm 0x553D34 (inline) sub_553774+0x102 Power management MSR read (0x1AA)
0x27 39 PowerMgmtSmm sub_553BC4 sub_553BE0+0x15C Power management - MSR save/restore trigger
Dynamic -1 TcgSmm sub_629574 sub_629A78+0x78 TCG/TPM 1.2 Physical Presence handler
Dynamic -1 TcgSmm sub_6297FC sub_629A78+0xAE TCG/TPM 1.2 Memory Override Request Control
Dynamic -1 TrEESmm sub_6225B4 sub_622AA4+0x7C TrEE/TPM 2.0 Physical Presence handler
Dynamic -1 TrEESmm sub_622818 sub_622AA4+0xAE TrEE/TPM 2.0 Memory Override Request Control

Note: "Dynamic" SW SMI numbers are allocated at runtime by the dispatch protocol (registered with value -1). The actual SW SMI# is assigned by PchSmiDispatcher and returned to the caller. TcgSmm and TrEESmm validate TPM presence via GUID-based checks before registering.

SX Dispatch Handlers

Protocol GUID: EFI_SMM_SX_DISPATCH2_PROTOCOL_GUID = {456D2859-A84B-4E47-A2EE-3276D886997D}

SX State Module Callback Function Description
S3 (Suspend-to-RAM) PowerMgmtSmm unk_5543C8 CPU power state save for S3
S4 (Suspend-to-Disk) SmmPlatform sub_A2710C Platform state save for S4
S5 (Soft-Off) SmmPlatform sub_A27148 Platform shutdown preparation

IO Trap Handlers

Protocol GUID: EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL_GUID = {58DC368D-7BFA-4E77-ABBC-0E29418DF930}

IO Port Width Module Callback Description
0x4000 1 byte PowerMgmtSmm sub_5539BC ACPI power management IO trap
0x4000 2 bytes PowerMgmtSmm sub_5541EC ACPI power management IO trap
0x4000 2 bytes SaLateInitSmm sub_5495D8 System Agent IO trap
Types 3-5 - PchInitSmm sub_584CD8 PCH IO trap handlers (loop registered)

USB Dispatch Handlers

Protocol GUID: EFI_SMM_USB_DISPATCH2_PROTOCOL_GUID = {EB346B97-975F-4A9F-8B22-F8E92BB3D569}

Module Callback Context Description
PchInitSmm sub_585284 Port 0x10061 USB legacy keyboard/mouse SMI
KbcEmulSMM off_A8C1F8 (vtable) - PS/2 keyboard controller emulation via USB

Power Button / NMI Handlers

Protocol GUID (Power Button): EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL_GUID = {1B1183FA-1823-46A7-8872-9C578755409D}

Module Callback Type Description
SmmPlatform sub_A272E8 PowerButtonEntry (0) Power button press handler
SmmNmiButton sub_42F824 NMI Dispatch NMI button handler (path A)
SmmNmiButton sub_42F8E8 Alt Dispatch (type 2) NMI button handler (path B)

Root SMI Handlers

Registered via gSmst->SmiHandlerRegister (no specific dispatch protocol):

Module Callback Description
PchSmiDispatcher sub_56DA84 Root hardware SMI handler - dispatches to all child protocols
PowerMgmtSmm sub_554004 / sub_553FA8 Conditional HW SMI (CPU feature dependent)
VariableSmm off_2972D8, off_2972F8 SMM variable service handlers
PchInitSmm nullsub_93 Placeholder/stub handler

Protocol / SmmCommunicate Handlers

Module Mechanism Description
SmiFlashSigned SmmCommunicate buffer Signed BIOS flash update (buffer at 0xA00000)
VariableSmmRuntimeDxe SmmCommunicate DXE-to-SMM bridge for GetVariable/SetVariable
HeciSmm Protocol install HECI/Intel ME communication (9 protocol methods)
SmmFaultTolerantWriteDxe ProtocolNotify Fault-tolerant flash write support

Vulnerability Analysis

All vulnerabilities were found in the SmiVariable module (SW SMI# 0xEF, handler sub_1F2EDC at 0x1F2EDC).

Architecture of the Vulnerable Handler

The SmiVariable handler uses an ACPI NVS shared memory buffer for communication with the OS:

OS (Ring 0)                          SMM (Ring -2)
============                         ==============
1. Write command struct to NVS buf
2. Write to IO port 0xB2 (SW SMI)
                                     3. Read NVS address via IO ports 0x26/0x27
                                     4. Dispatch on command byte (NVS[1])
                                     5. Process command using NVS fields
                                     6. Write status to NVS status field
7. Read result from NVS buf

The handler supports 10+ commands dispatched via BYTE1(NVS[0]):

Cmd Function Description
1 GetVariable Read UEFI variable
2 SetVariable Write UEFI variable
3 SetVariable (named) Write variable with name/GUID from NVS
4 GetHiiDB Read HII database pointer
6 Password check (single) Verify/set single password
7 Password check (triple) Verify/set admin + user + new password
8 Password status Check password authentication status
9 Setup lock Lock setup with password verification
10 Setup unlock Unlock setup with password verification

V1 - Missing SMRAM Pointer Validation (Cases 6/7)

Severity: CRITICAL CWE: CWE-125 (Out-of-bounds Read), CWE-20 (Improper Input Validation) Location: sub_1F2EDC at 0x1F301D (case 7) and 0x1F309A (case 6)

Description

In commands 6 and 7, the handler reads 32-bit pointer values from the ACPI NVS shared memory buffer and passes them directly to the password verification function sub_1F29D8 without validating them against SMRAM ranges.

Case 7 - Disassembly Evidence

; Read three pointers from attacker-controlled NVS buffer
0x1F301D:  mov  r15d, [rdi+4]      ; pointer from NVS+4  (attacker-controlled)
0x1F3021:  mov  r12d, [rdi]        ; pointer from NVS+0  (attacker-controlled)
0x1F3024:  mov  esi, [rdi+8]       ; pointer from NVS+8  (attacker-controlled)

; Validate NVS structure itself - does NOT validate embedded pointers
0x1F3027:  mov  edx, 0Ch
0x1F302C:  mov  rcx, rdi           ; address = NVS buffer base
0x1F302F:  call sub_1F3680         ; SmmIsBufferOutsideSmmValid(NVS, 12) - OK but insufficient

; Use UNVALIDATED pointer directly
0x1F3049:  mov  rcx, rsi           ; rcx = pointer from NVS+8 (NOT validated!)
0x1F304C:  call sub_1F29D8         ; Dereferences rcx as password string pointer

; Use second UNVALIDATED pointer
0x1F305B:  mov  rcx, r15           ; rcx = pointer from NVS+4 (NOT validated!)
0x1F305E:  call sub_1F29D8         ; Dereferences rcx

; Use third UNVALIDATED pointer
0x1F307A:  mov  rcx, r12           ; rcx = pointer from NVS+0 (NOT validated!)
0x1F307D:  call sub_1F29D8         ; Dereferences rcx

Case 6 - Same Pattern

0x1F309A:  mov  ebx, [rdi+4]      ; size/flags from NVS+4
0x1F309D:  mov  esi, [rdi]         ; pointer from NVS+0  (attacker-controlled)

0x1F309F:  mov  edx, 8
0x1F30A4:  mov  rcx, rdi
0x1F30A7:  call sub_1F3680         ; Validates NVS structure only

0x1F30B6:  mov  ecx, ebx          ; NVS+4 used as flags (not a pointer issue)
0x1F30B8:  call sub_1F29D8

0x1F30D8:  mov  rcx, rsi          ; UNVALIDATED pointer from NVS+0!
0x1F30DB:  call sub_1F29D8         ; Dereferences rsi as password string

Contrast with Safe Cases (1 & 2)

Cases 1 and 2 correctly validate embedded pointers:

; Case 2 - CORRECT validation of embedded pointer
0x1F3114:  mov  ecx, [rdi+10h]    ; data buffer pointer from NVS
0x1F3117:  mov  rdx, [rbp+var_10] ; data size from NVS
0x1F311B:  call sub_1F3680         ; Validates data buffer against SMRAM - CORRECT

Impact

An OS-level attacker can:

  1. Set pointer fields in NVS buffer to point into SMRAM (TSEG, typically below 4GB)
  2. Trigger SW SMI# 0xEF with command 6 or 7
  3. The handler reads up to 30 bytes from each SMRAM pointer (bounded by the loop in sub_1F29D8)
  4. Read data is hashed and compared against stored password hashes
  5. The pass/fail result is written back to the NVS status field
  6. This creates an SMRAM content oracle exploitable through differential analysis

V2 - Broken Post-Read Validation in Password Function

Severity: CRITICAL CWE: CWE-125 (Out-of-bounds Read), CWE-367 (TOCTOU Race Condition) Location: sub_1F29D8 at 0x1F29D8

Description

The password verification function sub_1F29D8 contains a call to the SMRAM validation function sub_1F3680, but it:

  1. Reads data from the user-controlled pointer before any validation
  2. Validates the wrong memory region (past the end of the read data)

Pseudocode

// sub_1F29D8 - Password verification
signed __int64 sub_1F29D8(__int16 *a1, char a2)
{
    if (a1) {                          // a1 = attacker-controlled pointer
        v7 = a1;
        v8 = 0;
        do {
            v9 = *v7;                  // READ from unvalidated pointer!
            v8 += 2;                   // Track bytes read
            ++v7;                      // Advance pointer
        } while (v9 && v8 < 0x1E);    // Read up to 30 bytes

        // BROKEN: validates [v7, v7+v8) = [END_of_string, END+length)
        // SHOULD validate [a1, a1+v8) = [START_of_string, START+length)
        if (!sub_1F3680(v7, v8))
            return EFI_INVALID_PARAMETER;
    }

    // Data already read - proceeds to hash and compare
    sub_1F3498(a1, hash_buffer, &hash_len);  // Hash the read data
    // ... compare against stored password hashes ...
}

Root Cause

After the read loop:

  • v7 = a1 + N (pointer past end of string, where N = characters read)
  • v8 = 2 * N (total bytes read)

The validation sub_1F3680(v7, v8) checks the region [a1+N, a1+N+2N) which is past the data that was already read. The correct call should be sub_1F3680(a1, v8) to validate the original buffer.

Impact

This bug means that even if V1 were fixed (i.e., cases 6/7 called sub_1F3680 before passing pointers to sub_1F29D8), the internal validation within sub_1F29D8 itself is broken and would not prevent SMRAM reads. The two bugs are independently exploitable but together represent a defense-in-depth failure.


V3 - Incomplete Pointer Validation in SetVariable Path

Severity: MEDIUM CWE: CWE-20 (Improper Input Validation) Location: sub_1F2BE0 at 0x1F2BE0 (called from case 3)

Description

Case 3 of the SmiVariable handler calls sub_1F2BE0 which handles named SetVariable operations. The function reads pointers from the NVS buffer and performs validation, but the variable name pointer check is insufficient:

// sub_1F2BE0 pseudocode
v1 = (WORD *)*(uint32 *)(a1 + 16);    // variable name pointer from NVS
v2 = (int16 *)*(uint32 *)(a1 + 32);   // password pointer from NVS

if (!sub_1F3680(a1, 36)                                    // NVS struct: CORRECT
  || !sub_1F3680(*(uint32*)(a1+28), *(uint32*)(a1+24))     // data buffer: CORRECT
  || !sub_1F3680(*(uint32*)(a1+16) + 2, 2))                // name ptr+2: ONLY 2 BYTES!
    return EFI_INVALID_PARAMETER;

The third validation only checks 2 bytes starting at name_pointer+2, not the full variable name string. A name string pointing into SMRAM would only have bytes 2-3 validated, while bytes 0-1 and 4+ are read without validation.

Additionally, the password pointer v2 (from NVS+32) is passed to sub_1F29D8 which has the broken validation (V2).

Impact

  • Partial SMRAM read via variable name string comparison
  • Password pointer goes through broken V2 validation path
  • Mitigated by the fact that the name must match a whitelist for direct SetVariable, but the comparison itself reads from the unvalidated pointer

V4 - Name String Iteration Before Validation

Severity: LOW CWE: CWE-125 (Out-of-bounds Read) Location: sub_1F2EDC case 1 at 0x1F3176

Description

In case 1 (GetVariable), after validating the NVS structure and data buffer, the handler iterates through the variable name string from a NVS-embedded pointer:

0x1F3176:  movzx eax, word ptr [rcx]   ; Read WCHAR from name pointer
0x1F3179:  add   rdx, 2
0x1F317D:  add   rcx, 2
0x1F3181:  test  ax, ax                 ; Check for null terminator
0x1F3184:  jz    validated
0x1F3186:  mov   eax, cs:dword_1F4280   ; Max length bound (256 bytes)
0x1F318C:  cmp   rdx, rax
0x1F318F:  jb    loop
0x1F3191:  call  sub_1F3680             ; Post-iteration validation

The name string is read character by character (up to 256 bytes) before the post-read validation. The post-read validation uses the same broken pattern as V2 (validates end of string, not start). However, case 1 does separately validate the data buffer pointer, making this a lower-severity issue than V1.


Clean Handler Analysis

The following SW SMI handlers were audited and found to contain no vulnerabilities:

SmmPlatform - SW SMI# 0xF0 (sub_A26BA4)

  • Function: Platform sleep preparation
  • Analysis: Exclusively performs PCI configuration space reads/writes (bus 0, device 31) and MMIO writes (0xE00F8094). All values are hardcoded constants or read from hardware registers. No user-controlled input is processed. Registers a protocol notify via gSmst->SmiHandlerRegister at the end.
  • Verdict: Safe - hardware-only operations with no attack surface

SmmPlatform - SW SMI# 0xF1 (sub_A26ED0)

  • Function: Platform wake restoration
  • Analysis: Simple PCI config space write to restore register values saved by 0xF0 handler. 6 lines of effective code.
  • Verdict: Safe - minimal code, no user input

SmmPlatform - SW SMI# 0x9F (sub_A27810)

  • Function: Dead/stub handler
  • Analysis: Function body is return 0; - a registered but unused handler.
  • Verdict: Safe - no-op

PowerMgmtSmm - SW SMI# 0x27 (sub_553BC4)

  • Function: MSR save/restore trigger
  • Analysis: Calls sub_553E68 which iterates over all CPU cores using gSmst->SmmStartupThisAp to execute an MSR save function. The save function (dword_553B3C -> sub_553D80) reads specific MSR values (0xCE, 0x1AA, and processor-specific MSRs) and stores them in a fixed SMRAM array. No user input.
  • Verdict: Safe - internal MSR operations only

PowerMgmtSmm - SW SMI# 0x28 (0x553D34)

  • Function: MSR read
  • Analysis: Inline code starting with mov ecx, 0x1AA; rdmsr. Reads a single MSR. No user input.
  • Verdict: Safe - single MSR read

TcgSmm - Physical Presence (sub_629574)

  • Function: TCG/TPM 1.2 Physical Presence request processing
  • Analysis: All input comes from UEFI variables (PhysicalPresence, PhysicalPresenceFlags) via SmmVariable->GetVariable. The handler validates TPM presence via a 16-byte GUID check (0x46E84F198B01E5B6 / 0xCC901B67531C93AB) before registration. Command validation uses explicit range checks and bitmask operations. No shared memory or CommBuffer processing.
  • Verdict: Safe - variable-only I/O with proper command validation

TcgSmm - Memory Clear (sub_6297FC)

  • Function: TCG MemoryOverwriteRequestControl
  • Analysis: Reads/writes only the MemoryOverwriteRequestControl UEFI variable. Simple logic: reads current value, conditionally clears bit 0, writes back.
  • Verdict: Safe - minimal variable-only logic

TrEESmm - Physical Presence (sub_6225B4)

  • Function: TrEE/TPM 2.0 Physical Presence request processing
  • Analysis: Structurally identical to TcgSmm's Physical Presence handler but operates on TrEEPhysicalPresence and TrEEPhysicalPresenceFlags variables. Uses a different TPM 2.0 GUID check (0x408CC2C3286BF25A / 0x17738B75E625B4B3).
  • Verdict: Safe - same pattern as TcgSmm

TrEESmm - Memory Clear (sub_622818)

  • Function: TrEE MemoryOverwriteRequestControl
  • Analysis: Identical logic to TcgSmm MOR handler, different variable GUID.
  • Verdict: Safe

Design Concerns

These are not exploitable vulnerabilities but represent security-relevant design decisions:

1. Password-Gated Operations Without Lockout

Commands 6, 7, 8, 9, and 10 in SmiVariable are gated by password verification (sub_1F29D8). However:

  • There is no brute-force lockout mechanism - unlimited attempts are possible
  • If the "Password" UEFI variable is unset (factory default), the empty-password comparison path in sub_1F29D8 may succeed, making the vulnerable code paths reachable without any authentication
  • The password hash comparison uses a simple scheme (no salting visible in the code)

2. TCG/TrEE Variable Protection

Both TPM handlers trust the PhysicalPresence / TrEEPhysicalPresence variables to contain the pending TPM operation. If these variables are not protected by VARIABLE_POLICY or VARIABLE_LOCK, an OS-level attacker could:

  • Set a pending TPM Clear operation
  • Trigger a reboot
  • The firmware would execute the TPM Clear on next boot

This is a known UEFI design concern and may be mitigated by platform-specific variable locking in other modules.

3. SmmPlatform SW SMI# 0xF0 Side Effects

The 0xF0 handler performs:

  • MMIO write: 0xE00F8094 &= 0xFFFFFFD0 (PCIe root complex register)
  • Multiple PCI config space modifications on bus 0, device 31
  • Installs a protocol via SmiHandlerRegister

If triggered at an unexpected time (outside of a genuine sleep transition), this could cause platform instability. The handler does not verify that a legitimate sleep transition is in progress.

4. Build Path Information Disclosure

The SmmErrorLog module contains a full Windows build path string:

c:\work7\spcsdgrnripcr\Build\GreenlowPcPkg\RELEASE_VS2013x86\X64\
GreenlowPlatPkg\Ras\Smm\SmmErrorLog\SmmErrorLog\DEBUG\AutoGen.c

This reveals:

  • Internal project name: "GreenlowPcPkg" (Intel Greenlow platform)
  • Build system: Visual Studio 2013 x86 cross-compiler
  • Build configuration: RELEASE (though DEBUG AutoGen.c is referenced)
  • Internal directory structure

Appendix A: Protocol GUID Reference

GUID Protocol Used By
18A3C6DC-5EEA-48C8-A1C1-B53389F98999 EFI_SMM_SW_DISPATCH2_PROTOCOL SmmPlatform, SmiVariable, PowerMgmtSmm, TcgSmm, TrEESmm
456D2859-A84B-4E47-A2EE-3276D886997D EFI_SMM_SX_DISPATCH2_PROTOCOL SmmPlatform, PowerMgmtSmm, PchInitSmm
58DC368D-7BFA-4E77-ABBC-0E29418DF930 EFI_SMM_IO_TRAP_DISPATCH2_PROTOCOL PowerMgmtSmm, SaLateInitSmm, PchInitSmm, PchSmiDispatcher
EB346B97-975F-4A9F-8B22-F8E92BB3D569 EFI_SMM_USB_DISPATCH2_PROTOCOL PchInitSmm, KbcEmulSMM, PchSmiDispatcher
1B1183FA-1823-46A7-8872-9C578755409D EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL SmmPlatform
514D2AFD-2096-4283-9DA6-700CD27DC7A5 PCH-specific dispatch protocol PchSmiDispatcher (installed), PchInitSmm (consumed)
9E71D609-6D24-47FD-B572-6140F8D9C2A4 PCH-specific dispatch protocol (GPI/TCO) PchSmiDispatcher (installed)
D52BB2B2-F022-49EC-86D2-7A293A7A054B PCH-specific dispatch protocol PchSmiDispatcher (installed)
3E7D2B56-3F47-42AA-8F6B-22F519818DAB PCH-specific dispatch protocol PchSmiDispatcher (installed)
83339EF7-9392-4716-8D3A-D1FC67CD55DB PCH-specific dispatch protocol PchSmiDispatcher (installed)
E6A81BBF-873D-47FD-B6BE-61B3E5720993 PCH-specific dispatch protocol PchSmiDispatcher (installed)
B3C14FF3-BAE8-456C-8631-27FE0CEB340C PCH-specific dispatch protocol (ICHN-like) PchSmiDispatcher (installed)
89843C0B-5701-4FF6-A473-65759904F735 Unknown (SmmReadyToLock related?) SmmPlatform

Appendix B: SMRAM Validation Function Analysis

sub_1F3680 - SmmIsBufferOutsideSmmValid

Location: 0x1F3680 (SmiVariable module) Prototype: bool sub_1F3680(uint64_t address, uint64_t size)

The decompiler incorrectly renders this function as return !a2 && !a1. The actual logic from disassembly:

1. Overflow check:
   - If size > max_address: REJECT
   - If address > max_address: REJECT
   - If size > 0 AND address > (max_address - size + 1): REJECT (integer overflow protection)

2. SMRAM range check (loop over SMRAM descriptors at qword_1F4418):
   For each SMRAM range [base, base+length):
     - If base > address: check if base < (address + size) -> REJECT (buffer extends into SMRAM)
     - If address >= base AND address < (base + length): REJECT (buffer starts in SMRAM)

3. Page-table validation (if byte_1F4284 is set):
   - Iterates page table entries at qword_1F4408
   - Validates buffer falls within a legitimate mapped region
   - Entry size from qword_1F4430, count from qword_1F4438

4. If all checks pass: return TRUE (buffer is valid/safe)
   Otherwise: return FALSE (buffer overlaps SMRAM or is invalid)

Assessment: The function itself is correctly implemented. The vulnerabilities arise from:

  • Not calling it on embedded pointers (V1)
  • Calling it with wrong arguments after the data is already read (V2)
  • Calling it with insufficient size (V3)

End of Report

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment