EDK II - NULL Pointer Dereference in XhcControlTransfer
In the GET_DESCRIPTOR hook of the XHCI DXE control transfer handler XhcControlTransfer (Xhci.c:1035-1075), three AllocateZeroPool calls have NO NULL CHECK before dereference.
- Advisory
- BYTERAY-2026-0247
- CWE
- CWE-690
- 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/Pci/XhciDxe/Xhci.c.
- Credit
- Argus-Systems
Executive Summary
In the GET_DESCRIPTOR hook of the XHCI DXE control transfer handler XhcControlTransfer (Xhci.c:1035-1075), three AllocateZeroPool calls have NO NULL CHECK before dereference. Line 1055 allocates ConfDesc sized by NumConfigurations from the USB device descriptor (attacker-controlled); line 1069 allocates ConfDesc[Index] sized by DataLength from the USB device; line 1074 allocates ActiveAlternateSetting. The PEI-phase counterpart (XhcPeim.c:692) correctly checks for NULL — confirming this is an isolated miss.
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/Pci/XhciDxe/Xhci.c:1055 - Function:
XhcControlTransfer - Category:
error_handling
Technical Details
Controllability: SEMI_TRUSTED — confidence: high. NumConfigurations and DataLength come directly from the USB device descriptor. A malicious USB device can choose these values, but they are bounded: NumConfigurations is a UINT8, so the line 1055 allocation is at most 255 * 8 = 2040 bytes on X64, and *DataLength must equal the descriptor's 16-bit TotalLength, so the line 1069 allocation is at most 65535 bytes. A device cannot make these allocations fail on a healthy system.
Data Flow
At line 1045, the device descriptor is copied from the physical USB device. At line 1055, ConfDesc = AllocateZeroPool(NumConfigurations * sizeof(...)) is sized by the attacker-controlled NumConfigurations with NO CHECK. At line 1069, ConfDesc[Index] = AllocateZeroPool(*DataLength) has NO CHECK. If the line 1055 allocation failed, the store to ConfDesc[Index] at line 1069 dereferences NULL. If the line 1069 allocation failed, CopyMem(ConfDesc[Index], Data, *DataLength) at line 1070 and the ConfDesc[Index]->NumInterfaces read at line 1074 dereference NULL. The PEI counterpart at XhcPeim.c:692 correctly checks NULL — confirming this DXE path is an isolated miss.
Affected Callers
UsbHcControlTransfer(UsbBusDxe/UsbUtility.c:187), which callsXhcControlTransferthroughEFI_USB2_HC_PROTOCOL.ControlTransferduring USB device enumeration.
Sanitization / Security Controls
- PEI counterpart (
XhcPeim.c:692) correctly checks NULL — confirming this DXE path is an isolated miss.
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
- Physical access to USB port; USB device attached; DXE pool already under severe memory pressure (the allocation sizes a device can request are too small to fail on their own).
- Device presents a device descriptor (
NumConfigurationsup to 0xFF) and a configuration descriptor (TotalLengthup to 0xFFFF). - Device connected;
XhcControlTransferprocesses the GET_DESCRIPTOR responses. - Under memory pressure,
AllocateZeroPoolfails returning NULL. CopyMemdereferences NULL.
Impact
Denial of service — firmware crash during USB descriptor processing, only when the DXE pool is already exhausted.
Remediation and Mitigation
As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Check the allocation result for NULL before dereferencing it and fail the operation cleanly when allocation fails. 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.