← ALL ADVISORIES

MEDIUM BYTERAY-2026-0288Disclosed

EDK II - Loop with Unreachable Exit Condition in PxeBcParseVendorOptions

PxeBcParseVendorOptions walks the PXE sub-options inside DHCP option 43 using a UINT8 Offset (line 93).

Advisory
BYTERAY-2026-0288
CWE
CWE-835
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 NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c.
Credit
Argus-Systems

Executive Summary

PxeBcParseVendorOptions walks the PXE sub-options inside DHCP option 43 using a UINT8 Offset (line 93). For every non-PAD sub-option it advances with Offset = (UINT8)(Offset + PxeOption->Length + 2) (line 197), where PxeOption->Length is a byte taken from the DHCP offer. The sum is truncated to 8 bits, so a sub-option whose Offset + Length + 2 equals 256 wraps Offset back to 0. The loop condition at line 102 (Offset < VendorOptionLen && PxeOption->OpCode != DHCP4_TAG_EOP) only checks the new offset, never whether it moved forward, so the parser returns to the first sub-option and repeats forever. The smallest trigger is a 2-byte option 43 containing a single sub-option header {0x80, 0xFE}: Offset goes from 0 to (UINT8)(0 + 254 + 2) = 0 on every iteration. The sub-option length is not checked against VendorOptionLen anywhere in the function.

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 (NetworkPkg)
  • Affected commit: 70741a15d9a714323a5598eac47727e60507e22f (master, 2026-06-21). The code is present on that commit and later revisions that have not changed it.
  • Location: NetworkPkg/UefiPxeBcDxe/PxeBcDhcp4.c:197
  • Function: PxeBcParseVendorOptions
  • Category: denial_of_service

Technical Details

Controllability: EXTERNAL_UNTRUSTED — confidence: high

Data Flow

A DHCPv4 OFFER from any host on the local network is received by Dhcp4Dxe, which validates only the top-level option framing (DhcpIterateBufferOptions, Dhcp4Option.c:333-343) and treats the content of option 43 as opaque. DhcpCallUser then invokes PxeBcDhcp4CallBack with Dhcp4RcvdOffer. The callback drops offers longer than 1472 bytes (PxeBcDhcp4.c:1281) and otherwise calls PxeBcCacheDhcp4Offer (line 1294), which copies the offer into Private->OfferBuffer[] and calls PxeBcParseDhcp4Packet (line 826). If option 60 starts with PXEClient (lines 523-528) and option 43 is present, PxeBcParseVendorOptions (Option, &Cache4->VendorOpt) is called at line 535. There VendorOptionLen = Dhcp4Option->Length (line 96), and the walk at lines 102-201 advances Offset with the 8-bit truncating addition at line 197.

Affected Callers

  • PxeBcParseDhcp4Packet (PxeBcDhcp4.c:535), reached from PxeBcCacheDhcp4Offer (line 826) for every received offer, and also from lines 642, 684 and 765 and PxeBcImpl.c:732 for cached ACK, proxy offer and PXE reply packets.

Sanitization / Security Controls

  • Option framing validation in Dhcp4Dxe (Dhcp4Option.c:333-343): ineffective. It checks that each top-level option fits the packet but does not look inside option 43.
  • Packet size check at PxeBcDhcp4.c:1281: ineffective. The trigger is only a few bytes.
  • Loop guard at PxeBcDhcp4.c:102: ineffective. It checks Offset < VendorOptionLen but not that Offset increased, and the addition at line 197 is truncated to UINT8.
  • Boot watchdog: not armed. BDS reads the PXE boot file through BmGetNextLoadOptionBuffer (BmBoot.c:2003) before it sets the 5-minute watchdog at BmBoot.c:2105, so nothing resets the platform while the parser spins.

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

Reproduction

  1. Attacker is on the same broadcast domain as the target and the target attempts IPv4 PXE boot.
  2. Attacker answers the target's DHCPDISCOVER with a DHCPOFFER (or a proxy offer with yiaddr 0.0.0.0) that copies the request's xid and client MAC address.
  3. The offer carries option 60 = PXEClient and option 43 with length 2 and data 80 FE, followed by the end option.
  4. PxeBcDhcp4CallBack caches the offer and PxeBcParseDhcp4Packet calls PxeBcParseVendorOptions.
  5. At line 197, Offset = (UINT8)(0 + 0xFE + 2) = 0; the loop condition at line 102 still holds, so the parser re-reads the same sub-option forever and the boot hangs.

Impact

Remote, unauthenticated denial of service of the firmware PXE boot. A single crafted DHCP offer makes the DHCP callback loop forever, so PXE boot never completes and the platform hangs until it is reset. No memory is read or written out of bounds.

Remediation and Mitigation

As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Use a wide enough type for the loop offset and ensure it always advances, so a crafted length cannot make the loop restart or spin forever. 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