EDK II - Integer Underflow in HttpBootDhcp4CallBack
The GET_OPTION_BUFFER_LEN macro in HttpBootDhcp4.h:166 is identical to the PXE variant: (Pkt)->Length - sizeof(EFI_DHCP4_HEADER) - 4.
- Advisory
- BYTERAY-2026-0237
- CWE
- CWE-191
- 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/HttpBootDxe/HttpBootDhcp4.h.
- Credit
- Argus-Systems
Executive Summary
The GET_OPTION_BUFFER_LEN macro in HttpBootDhcp4.h:166 is identical to the PXE variant: (Pkt)->Length - sizeof(EFI_DHCP4_HEADER) - 4. It underflows when Packet->Length is in [236, 239], wrapping to approximately 0xFFFFFFFC. This value is passed to HttpBootParseDhcp4Options (HttpBootDhcp4.c:608–612) as the Length bound, causing the while(Offset < Length) loop to read Option->OpCode and Option->Length out of bounds from heap memory. The callback is reached via DhcpHandleSelect → DhcpCallUser because DHCP_IS_BOOTP(NULL) returns TRUE (Para is NULL since DhcpValidateOptions is skipped for Length <= 240). The same write-amplification risk exists: if the OOB heap matches DHCP4_TAG_MAXMSG, CopyMem at line 615 writes 2 bytes to an OOB heap address. The value written is fixed (HTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE), line 614). A secondary path exists through HttpBootCacheDhcp4Offer → HttpBootParseDhcp4Packet → GET_OPTION_BUFFER_LEN at line 283, which underflows again; there the scan starts in the fixed-size offer cache Private->OfferBuffer[], so the out-of-bounds part begins later than on the direct path.
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/HttpBootDxe/HttpBootDhcp4.h:166 - Function:
HttpBootDhcp4CallBack (via GET_OPTION_BUFFER_LEN macro) - Category:
Integer Underflow / Out-of-Bounds Read & Write
Technical Details
Controllability: EXTERNAL_UNTRUSTED — confidence: high
Data Flow
A remote DHCP4 OFFER packet with attacker-controlled TotalSize in [236, 239] arrives at DhcpInput (Dhcp4Io.c:963). The receive guard checks only TotalSize >= 236, so the crafted packet passes. Packet->Length is set to the attacker-controlled size at Dhcp4Io.c:979. Because Packet->Length <= 240, DhcpValidateOptions is skipped, leaving Para = NULL. DHCP_IS_BOOTP(NULL) returns TRUE, bypassing the DhcpHandleSelect guard (Dhcp4Io.c:611). DhcpCallUser dispatches the undersized packet to HttpBootDhcp4CallBack (Dhcp4Io.c:624). Path A (direct): The callback evaluates GET_OPTION_BUFFER_LEN(Packet) at HttpBootDhcp4.h:166, computing 236 - 236 - 4 = 0xFFFFFFFC. This is passed to HttpBootParseDhcp4Options (HttpBootDhcp4.c:608), whose while(Offset < 0xFFFFFFFC) loop reads Option->OpCode and Option->Length out of bounds from heap (sinks at lines 188 and 202). If a byte == 57 is encountered, CopyMem at line 615 writes the fixed 2-byte value HTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE) to an OOB heap address. Path B (secondary): On Dhcp4RcvdOffer, HttpBootCacheDhcp4Offer (HttpBootDhcp4.c:652) caches the undersized packet (only an upper-bound check at line 639), then HttpBootParseDhcp4Packet (HttpBootDhcp4.c:468) calls GET_OPTION_BUFFER_LEN(Offer) at line 283, which underflows again to 0xFFFFFFFC, triggering the same OOB read loop starting from the cached copy in Private->OfferBuffer[].
Affected Callers
DhcpHandleSelectDhcpCallUserHttpBootCacheDhcp4OfferHttpBootParseDhcp4Packet
Sanitization / Security Controls
- Receive guard (
Dhcp4Io.c:963,TotalSize >= 236): Ineffective — threshold lower than the macro's 240-byte requirement. DhcpValidateOptions(Dhcp4Io.c:999): Bypassed — gated onLength > 240.DhcpHandleSelectOFFER validation (Dhcp4Io.c:611): Bypassed —DHCP_IS_BOOTP(NULL) = TRUE.- Upper-bound check (
HttpBootDhcp4.c:639,Length <= HTTP_BOOT_DHCP4_PACKET_MAX_SIZE): Ineffective — only checks upper bound; no lower-bound enforcement before callingHttpBootCacheDhcp4Offer, which hits the secondary underflow path at line 283.
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: High
Reproduction
- Attacker monitors for the victim's DHCP4 DISCOVER during HTTP boot.
- Attacker crafts a DHCP4 OFFER with
TotalSize= 236–239 bytes (fullEFI_DHCP4_HEADER, truncated before magic cookie/options). - OFFER passes basic checks (spoofed
OpCode,Xid,ClientHwAddrfrom sniffed DISCOVER). - Attacker sends the crafted OFFER.
- Receive guard passes,
DhcpValidateOptionsskipped,Para = NULL,DHCP_IS_BOOTP(NULL) = TRUE,DhcpCallUserinvokesHttpBootDhcp4CallBack. - Path A (direct):
GET_OPTION_BUFFER_LENat line 610 underflows to 0xFFFFFFFC;HttpBootParseDhcp4Optionsscans OOB heap until it meets a 0xFF (end) byte or the requested tag. - Path B (secondary):
HttpBootCacheDhcp4Offercaches the undersized packet;HttpBootParseDhcp4PacketcallsGET_OPTION_BUFFER_LENat line 283, underflowing again. - On Path A, if the scan stops on an OOB byte == 57,
CopyMemat line 615 writes the fixed 2-byte valueHTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE)to OOB heap, corrupting adjacent data.
Impact
Pre-auth adjacent-network OOB read past the received packet via two code paths, which can crash the boot if it reaches unmapped memory, plus a limited OOB heap write on the direct path: a fixed 2-byte value (HTONS (HTTP_BOOT_DHCP4_PACKET_MAX_SIZE)) written after the first out-of-bounds byte equal to 57, which can corrupt adjacent heap data. The read results are not returned to the attacker.
Remediation and Mitigation
As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Validate the length against its minimum before the subtraction so it cannot underflow. 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.