← ALL ADVISORIES

LOW BYTERAY-2026-0242Disclosed

EDK II - NULL Pointer Dereference in XhcInitSched

In XhcInitSched, three allocations use ASSERT-only guards before dereference.

Advisory
BYTERAY-2026-0242
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/XhciSched.c.
Credit
Argus-Systems

Executive Summary

In XhcInitSched, three allocations use ASSERT-only guards before dereference. Dcbaa at line 522 is allocated for the Device Context Base Address Array; ScratchEntryMap at line 538 and ScratchEntry at line 545 are sized by MaxScratchpadBufs which comes from hardware registers (HcSParams2). In a RELEASE build, a failed allocation is dereferenced as NULL. The hardware cannot force the failure: ScratchBufHi and ScratchBufLo are 5-bit fields (XhciReg.h:109,111), so MaxScratchpadBufs is at most 1023 and each scratchpad bookkeeping allocation is at most 8 KB, and Dcbaa is (MaxSlotsEn + 1) * 8 bytes with an 8-bit MaxSlots, at most 2 KB. Failure requires the system to be out of memory during controller initialization.

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/XhciSched.c:522
  • Function: XhcInitSched
  • Category: error_handling

Technical Details

Controllability: SEMI_TRUSTED — confidence: high. MaxScratchpadBufs comes from the HcSParams2 hardware register, but its 10-bit width keeps the allocation sizes small; the trigger is allocation failure under memory exhaustion.

Data Flow

At line 522, Dcbaa = UsbHcAllocateMem(...) with ASSERT-only at 523, then ZeroMem(Dcbaa, Entries) at 524. At lines 538–540, ScratchEntryMap = AllocateZeroPool(sizeof(UINTN) * MaxScratchpadBufs) with ASSERT-only, sized by hardware register value. At lines 545–546, ScratchEntry follows the same pattern. MaxScratchpadBufs is built from two 5-bit fields at line 531 (at most 1023), so these allocations are at most 8 KB; a NULL return only occurs under memory exhaustion, after which ScratchEntry[Index] and ScratchEntryMap[Index] are written through NULL in the loop at lines 566–582.

Affected Callers

  • XhcReset (Xhci.c:214)
  • XhcDriverBindingStart (Xhci.c:2102)

Sanitization / Security Controls

  • ASSERT — DEBUG-only.

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. RELEASE build with an xHCI controller present.
  2. Exhaust boot services memory (or inject allocation failure) before XhcInitSched runs from XhcDriverBindingStart or XhcReset.
  3. XhcInitSched allocates Dcbaa (at most 2 KB), ScratchEntryMap, and ScratchEntry (at most 8 KB each).
  4. One of these allocations fails, returning NULL.
  5. ASSERT guards compile to no-ops in RELEASE builds; ZeroMem (for Dcbaa) or the scratchpad loop (for ScratchEntry / ScratchEntryMap) dereferences NULL.

Impact

Denial of service — firmware crash during XHCI controller initialization, only when memory is already exhausted. A malicious xHCI device cannot force this path, and such a device already has DMA access.

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.

References