← ALL ADVISORIES

LOW BYTERAY-2026-0257Disclosed

EDK II - NULL Pointer Dereference in Split

In the XenStore string-list parsing helper Split, Dst = AllocatePool(*NumPtr * sizeof(CHAR8 *) + Len) has NO NULL CHECK before CopyMem at line 233 writes through it via &Dst[*NumPtr].

Advisory
BYTERAY-2026-0257
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 OvmfPkg/XenBusDxe/XenStore.c.
Credit
Argus-Systems

Executive Summary

In the XenStore string-list parsing helper Split, Dst = AllocatePool(*NumPtr * sizeof(CHAR8 *) + Len) has NO NULL CHECK before CopyMem at line 233 writes through it via &Dst[*NumPtr]. The *NumPtr count and Len derive from host-controlled XenStore ring data. A hostile XenStore backend can make this allocation fail: Len comes from the UINT32 Header.len with no upper bound, and *NumPtr can be as large as Len (an all-NUL body), while the earlier Body allocation of Len + 1 bytes can still succeed. On failure the CopyMem destination is NULL + *NumPtr * sizeof(CHAR8 *), a non-zero address, so the result is a Len-byte write of host data at a host-influenced low address rather than a plain NULL-page access.

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 (OvmfPkg)
  • Affected commit: 70741a15d9a714323a5598eac47727e60507e22f (master, 2026-06-21). The code is present on that commit and later revisions that have not changed it.
  • Location: OvmfPkg/XenBusDxe/XenStore.c:232
  • Function: Split (static helper at line 212)
  • Category: error_handling

Technical Details

Controllability: SEMI_TRUSTED — confidence: high. NumPtr and Len derive from host-controlled XenStore ring data via the Split function. The XenStore backend (dom0/xenstored) is trusted by a normal Xen HVM guest, and OVMF has no Xen confidential-guest mode.

Data Flow

At line 229, *NumPtr = ExtractStrings(Strings, Len, NULL) derives from host-controlled ring data. At line 232, Dst = AllocatePool(*NumPtr * sizeof(CHAR8 *) + Len) is sized by host-controlled values with NO NULL CHECK. At line 233, CopyMem((VOID *)&Dst[*NumPtr], Strings, Len) writes through the NULL-based pointer. Called from XenStoreProcessMessage at line 647 for XS_WATCH_EVENT messages with host-controlled Body and Header.len (read at lines 628-636), and from XenStoreListDirectory at line 1230 with the reply to an XS_DIRECTORY request.

Affected Callers

  • XenStoreProcessMessage
  • XenStoreListDirectory

Sanitization / Security Controls

  • None.

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 controls the XenStore backend (dom0/xenstored); guest processes XenStore directory listing/watch event.
  2. Host sends a XenStore message with a large Header.len and a body made mostly of NUL bytes.
  3. Split parses host data producing large NumPtr (up to Len).
  4. AllocatePool(*NumPtr * sizeof(CHAR8 *) + Len) fails.
  5. CopyMem writes Len host bytes to address *NumPtr * sizeof(CHAR8 *).

Impact

Guest firmware crash, or a write of host-supplied bytes to a low guest address derived from the string count, during XenStore message processing. Only the XenStore backend can trigger it, and that backend is already trusted by the guest.

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