EDK II - Out-of-Bounds Read in HttpBootParseDhcp6Options
HttpBootParseDhcp6Options iterates over DHCP6 options using a loop guarded only by Offset < Length (line 149).
- Advisory
- BYTERAY-2026-0230
- CWE
- CWE-130
- 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/HttpBootDhcp6.c.
- Credit
- Argus-Systems
Executive Summary
HttpBootParseDhcp6Options iterates over DHCP6 options using a loop guarded only by Offset < Length (line 149). The loop body reads the 4-byte option header via struct pointer (Option->OpCode at line 150, Option->OpLen at line 154) without verifying Offset+4 <= Length. Loop advancement uses Offset += (NTOHS(Option->OpLen) + 4) (line 154).
The larger problem is the Length the caller passes. HttpBootParseDhcp6Packet (lines 230-234) calls the walker with Buffer = Option->Data + 12 and Length = NTOHS(Option->OpLen) of the IA_NA option. That length is 12 bytes too long (it does not subtract the 12 bytes skipped), and the IA_NA OpLen is never checked against the packet: the outer loop at lines 204-222 only checks that each option starts inside the packet. The outer loop keeps the last IA_NA it sees by opcode (lines 205-206), while Dhcp6Dxe only bounds-checks the IA_NA that carries the client's own IAID (Dhcp6SeekIaOption, Dhcp6Io.c:846-885). A trailing IA_NA with a foreign IAID and OpLen up to 0xFFFF therefore reaches the walker, and inner OpLen values move the cursor up to about 64 KB past the start of the IA option. The packet is cached in the fixed entry Private->OfferBuffer[n].Dhcp6 (HTTP_CACHED_DHCP6_PACKET_MAX_SIZE, HttpBootDhcp6.h:71,76) inside HTTP_BOOT_PRIVATE_DATA, so these reads can go past the end of that pool allocation. This is the same vulnerable shape as Dhcp6SeekOption, relocated into the HttpBootDxe HTTP boot driver's helper parser.
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/HttpBootDhcp6.c:149, call siteNetworkPkg/HttpBootDxe/HttpBootDhcp6.c:230-234 - Function:
HttpBootParseDhcp6Options - Category: CWE-130 — Out-of-bounds read in DHCP6 option walker
Technical Details
Controllability: EXTERNAL_UNTRUSTED — high confidence. DHCP6 IA option inner data from remote HTTP boot packet. No authentication.
Data Flow
Remote DHCP6 server → HttpBootDhcp6CallBack (line 417) → HttpBootCacheDhcp6Offer (line 474) → HttpBootParseDhcp6Packet (line 379). The outer loop (lines 204-222) records the last IA_NA option by opcode without checking its OpLen against the packet. HttpBootParseDhcp6Packet (line 230) then calls HttpBootParseDhcp6Options(Option->Data + 12, NTOHS(Option->OpLen), DHCP6_OPT_STATUS_CODE) on IA option inner data, with a length 12 bytes larger than the remaining IA data and not bounded by the packet. The loop at line 149 (while (Offset < Length)) reads Option->OpCode and Option->OpLen via struct pointer without verifying Offset+4 <= Length. Loop advancement: Offset += (NTOHS(Option->OpLen) + 4), so attacker-chosen inner lengths move the cursor up to about 64 KB past the IA option, beyond the cached packet in Private->OfferBuffer[].
Affected Callers
HttpBootParseDhcp6Packet
Sanitization / Security Controls
- Packet size check at
HttpBootDhcp6CallBackline 461 (Packet->Length > HTTP_BOOT_DHCP6_PACKET_MAX_SIZEis dropped): ineffective: bounds the cached packet, not the IA_NAOpLenor the inner option walk. Dhcp6SeekIaOption/Dhcp6SeekInnerOptionSafein Dhcp6Dxe (Dhcp6Io.c:846-885): ineffective: only applied to the IA_NA matching the client's IAID; HttpBoot uses the last IA_NA in the packet.
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: Medium
Reproduction
- IPv6 HTTP boot; attacker is an on-link rogue DHCP6 server or can MITM the DHCP6 exchange.
- Craft a DHCP6 Advertise with a valid IA_NA for the client's IAID, followed by a second, trailing IA_NA with a different IAID and
OpLen0xFFFF whose inner sub-options carry largeOpLenvalues and no status code option. - Send the crafted DHCP6 Advertise;
HttpBootParseDhcp6Optionswalks past the cached packet.
Impact
Out-of-bounds read of up to about 64 KB past the cached DHCPv6 packet during HTTP boot IA option parsing, which can run past the HTTP_BOOT_PRIVATE_DATA pool allocation. The bytes read only select the IsProxyOffer flag (line 235); nothing is returned to the attacker. A read into unmapped or guard memory faults and stops the boot (denial of service).
Remediation and Mitigation
As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Before reading each option header or field, verify that the full field fits within the remaining buffer length, not just that the cursor currently sits in bounds. 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.