← ALL ADVISORIES

HIGH BYTERAY-2026-0226Disclosed

EDK II - Improper Validation of Array Index in UsbSelectConfig

The DXE-phase function UsbSelectConfig loops (line 412) on the untrusted NumInterfaces field from the USB configuration descriptor and writes a pointer to each newly created USB_INTERFACE into the fixed-size array Device->Interfaces[USB_MAX_INTERFACE] (16 entries, UsbBus.h:45,178) at line 431.

Advisory
BYTERAY-2026-0226
CWE
CWE-129
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 MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c.
Credit
Argus-Systems

Executive Summary

The DXE-phase function UsbSelectConfig loops (line 412) on the untrusted NumInterfaces field from the USB configuration descriptor and writes a pointer to each newly created USB_INTERFACE into the fixed-size array Device->Interfaces[USB_MAX_INTERFACE] (16 entries, UsbBus.h:45,178) at line 431. The only guard is an ASSERT, which is a no-op in RELEASE builds. This is the DXE equivalent of the PEI-phase vulnerability in PeiUsbGetAllConfiguration.

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 (MdeModulePkg)
  • Affected commit: 70741a15d9a714323a5598eac47727e60507e22f (master, 2026-06-21). The code is present on that commit and later revisions that have not changed it.
  • Location: MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c:431
  • Function: UsbSelectConfig
  • Category: other

Technical Details

Controllability: EXTERNAL_UNTRUSTED — Confidence: High

Data Flow

The loop bound derives from NumInterfaces (attacker-controlled UINT8, range 0–255). UsbParseConfigDesc (UsbDesc.c:355-421) allocates Config->Interfaces for any NumInterfaces without a cap; it only requires each interface descriptor's InterfaceNumber to be below NumInterfaces, and each interface needs at least one setting or line 418 dereferences a NULL Settings[0]. The array Device->Interfaces has a fixed size of 16. No runtime check exists to prevent Index from exceeding the array bounds in production firmware. Indices 16 and above overwrite the following USB_DEVICE fields (Translator, ParentAddr, ParentIf, ParentPort, Tier, DisconnectFail) and then pool memory past the end of the USB_DEVICE allocation, up to 239 pointer slots (about 1.9 KB on X64). The written values are firmware heap pointers to the new USB_INTERFACE objects, not attacker-chosen values.

Affected Callers

  • UsbEnumerateNewDev (UsbEnumer.c:843), when a new device is enumerated on a hub or root hub port.
  • UsbIoControlTransfer (UsbBus.c:187), on a SET_CONFIGURATION request.
  • UsbIoPortReset (UsbBus.c:916), after a port reset.

Sanitization / Security Controls

The only guard is ASSERT (Index < USB_MAX_INTERFACE) at line 430, which compiles to a no-op in RELEASE firmware builds. No runtime bounds check prevents Index from exceeding the array bounds in production firmware.

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: Medium
Realism: Medium

Reproduction

  1. Attacker constructs a malicious USB device configured to present crafted USB descriptors with NumInterfaces set to a value > 16 (e.g., 255), followed by one interface descriptor (9 bytes) for each interface number 0 through NumInterfaces - 1.
  2. Attacker plugs the device into the target machine and powers it on (or forces a reboot).
  3. During DXE phase, UsbEnumerateNewDev enumerates the device and calls UsbSelectConfig.
  4. UsbSelectConfig iterates beyond array bounds, writing pointers to new USB_INTERFACE objects past Device->Interfaces into the rest of USB_DEVICE and adjacent DXE heap memory.
  5. The resulting heap corruption crashes or destabilizes the DXE phase.

Impact

A malicious USB device causes an out-of-bounds write of heap pointers past Device->Interfaces, corrupting the rest of the USB_DEVICE structure and adjacent DXE pool memory. This reliably corrupts the DXE heap and can crash or hang the boot. The written values are firmware-chosen pointers, so turning the corruption into code execution in DXE would require additional heap grooming and is not demonstrated.

Remediation and Mitigation

As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Validate the array index against the number of elements before using it to read or write the array. 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