← ALL ADVISORIES

LOW BYTERAY-2026-0241Disclosed

EDK II - Variadic Function Argument Mismatch in DumpErrorNotificationType

A copy-paste error at lines 199 and 201 of HestParser.c causes incorrect argument handling in variadic Print() calls.

Advisory
BYTERAY-2026-0241
CWE
CWE-688
Vendor
TianoCore
Product
EDK II
Reported
2026-06-25
Disclosure
2026-10-29
Affected
EDK II at commit 70741a15d9a714323a5598eac47727e60507e22f (master, 2026-06-21); affected code in ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c.
Credit
Argus-Systems

Executive Summary

A copy-paste error at lines 199 and 201 of HestParser.c causes incorrect argument handling in variadic Print() calls. At line 201, Print(L"UNKNOWN(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]) passes a CONST CHAR16* pointer where the %x format specifier expects an integer. At line 199, Print(L"%s(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]) has two format specifiers (%s + %x) but only one argument, leaving %x to read an uninitialized stack slot. The intended arguments should include *Ptr (a UINT8 type value from the ACPI HEST table), as in the sibling calls EinjParser.c:241 and EinjParser.c:272 (Print(L"%s(0x%x)", Name, Value)). Line 201 also indexes the array out of bounds: it runs only when *Ptr is greater than EFI_ACPI_6_5_HARDWARE_ERROR_NOTIFICATION_SOFTWARE_DELEGATED_EXCEPTION (0x0B), while HestErrorNotificationStructureTypeStr (lines 28-41) has 12 entries, so for any type value from 0x0C to 0xFF it reads a pointer-sized value past the end of the array. That value is only printed with %x, never dereferenced.

This advisory is one of a set reported to VulnCheck on 2026-06-25 for coordinated disclosure to the EDK II maintainers. After several follow-ups over the following months no response was received. 126 days after the initial report, ByteRay is publishing the findings in good faith so that affected integrators can assess and remediate them. All findings were identified against EDK II commit 70741a15d9a714323a5598eac47727e60507e22f (master, 2026-06-21).

Affected Products and Versions

  • Vendor: TianoCore
  • Product: EDK II (ShellPkg)
  • Affected commit: 70741a15d9a714323a5598eac47727e60507e22f (master, 2026-06-21). The code is present on that commit and later revisions that have not changed it.
  • Location: ShellPkg/Library/UefiShellAcpiViewCommandLib/Parsers/Hest/HestParser.c:201, HestParser.c:199
  • Function: DumpErrorNotificationType
  • Category: error_handling

Technical Details

Controllability: SEMI_TRUSTED — confidence: high

Data Flow

An operator invokes the acpiview -s HEST UEFI shell command at UefiShellAcpiViewCommandLib.c:356, causing AcpiView() to read ACPI tables from firmware memory. ProcessAcpiTable() at AcpiTableParser.c:181 receives a pointer to the ACPI HEST table buffer. The ParseAcpi() loop at AcpiParser.c:765 iterates parser entries and invokes the DumpErrorNotificationType PrintFormatter callback with Ptr pointing to the Type byte in the ACPI table. Inside DumpErrorNotificationType at HestParser.c:189, *Ptr reads the UINT8 Type byte from the ACPI HEST table. At line 199, Print(L"%s(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]) has two format specifiers but one argument, causing %x to read an uninitialized stack slot. At line 201, the vulnerable sink Print(L"UNKNOWN(0x%x)", HestErrorNotificationStructureTypeStr[*Ptr]) passes a CONST CHAR16* pointer where %x expects an integer — a copy-paste bug that should have used *Ptr. Because this branch is taken only for *Ptr > 0x0B, the index is always past the end of the 12-entry array, so the pointer printed is read out of bounds.

Affected Callers

  • ParseAcpi (AcpiParser.c:765, called for HestErrorNotificationParser at HestParser.c:459)

Sanitization / Security Controls

  • UEFI Shell access requirement: The acpiview command is only available in the UEFI shell environment, requiring physical or console access to the machine. This is an effective control.
  • Trust boundary — self-injection: The operator running acpiview already has full UEFI shell console access. The informational leak (pointer value printed as hex, uninitialized stack value on line 199) is displayed to the same operator who already holds equal or greater privilege.
  • *Ptr range check (HestParser.c:198): only selects between the two Print branches; both are wrong, and the else branch still indexes the array with the out-of-range value. Ineffective.
  • ValidateErrorNotificationType validator (HestParser.c:242): runs after the PrintFormatter in ParseAcpi (AcpiParser.c:791-798), so it cannot prevent the bad Print. Ineffective.
  • No sanitization points exist along the data flow path.

Reachability and Preconditions

Attacker position and trust level for this issue are stated in the Controllability line and Data Flow above, and the concrete trigger is in Reproduction below.

Exploitability: Low
Realism: Low

Reproduction

  1. Attacker has physical or remote console access to the UEFI Shell environment; machine must have a HEST table with Hardware Error Notification Structures (common on server/enterprise hardware).
  2. Run acpiview -s HEST.
  3. When a Hardware Error Notification Structure is encountered, DumpErrorNotificationType is called.
  4. For a type value 0x00-0x0B, line 199 prints an unrelated stack or register value for %x; for a type value 0x0C-0xFF, line 201 reads a pointer past the end of HestErrorNotificationStructureTypeStr and displays it as hex instead of the intended byte value.

Impact

Minimal — cosmetic garbage display, a potential stack value leak, and (for type values above 0x0B) a pointer-sized value read past the end of a static array, all printed only to the same operator who already has console access. No privilege escalation, code execution, or remote data exfiltration.

Remediation and Mitigation

As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Pass the intended argument to the formatting routine and bound the array index used to select it. The specific control that is absent or ineffective is identified in the Sanitization / Security Controls list under Technical Details.

Timeline

  • 2026-06-25 - Reported to VulnCheck for coordinated disclosure to the TianoCore / EDK II security team.
  • 2026-07 to 2026-10 - Several follow-ups sent; no response received.
  • 2026-10-29 - Public disclosure in good faith, 126 days after the initial report.

Credits

Discovered and reported by Argus-Systems.

References