← ALL ADVISORIES

LOW BYTERAY-2026-0282Disclosed

EDK II - Out-of-Bounds Read in DhcpInput

A remote pre-auth network attacker can send a DHCPv4 reply packet with HwAddrLen > 16 (range 0–255) during PXE/DHCP boot.

Advisory
BYTERAY-2026-0282
CWE
CWE-125
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/Dhcp4Dxe/Dhcp4Io.c.
Credit
Argus-Systems

Executive Summary

A remote pre-auth network attacker can send a DHCPv4 reply packet with HwAddrLen > 16 (range 0–255) during PXE/DHCP boot. The value flows directly into CompareMem(DhcpSb->ClientAddressSendOut, Head->ClientHwAddr, Head->HwAddrLen) where ClientAddressSendOut is a fixed 16-byte array inside the heap-allocated DHCP_SERVICE struct. No upstream code validates Head->HwAddrLen before this compare — the only pre-check (line 963) validates total packet size, and DhcpValidateOptions (line 1001) runs after the compare and only validates DHCP options. With HwAddrLen=255, CompareMem may read up to 239 bytes past the 16-byte buffer into adjacent DHCP_SERVICE heap fields (ActiveChild pointer, ActiveConfig, Timer, etc.). CompareMem stops at the first differing byte (MemLibGeneric.c:131), so it only reads past byte 16 while the attacker's bytes (which come from its own ServerName field, following ClientHwAddr in the header) match the struct contents.

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/Dhcp4Dxe/Dhcp4Io.c:990
  • Function: DhcpInput
  • Category: Out-of-bounds read (CWE-125/CWE-805)

Technical Details

Controllability: EXTERNAL_UNTRUSTED — confidence: high

Data Flow

The vulnerability originates from a remote attacker on the same network broadcast domain sending a DHCP/UDP packet during PXE boot. DhcpInput is registered as a pre-auth UDP receive callback via UdpIoRecvDatagram at Dhcp4Driver.c:318. When a packet arrives, the entry point at Dhcp4Io.c:927 receives the raw attacker-controlled DHCP packet. A size check at line 963 validates only that TotalSize >= sizeof(EFI_DHCP4_HEADER) but does not inspect individual header fields. At line 979, NetbufCopy copies the attacker's bytes verbatim into the EFI_DHCP4_HEADER struct, making Head->HwAddrLen (a packed UINT8 at offset 2, range 0–255 per Dhcp4.h:53) fully attacker-controlled. The destination buffer ClientAddressSendOut[16] is a fixed 16-byte array inside the heap-allocated DHCP_SERVICE struct (declared at Dhcp4Impl.h:108), immediately followed by the ActiveChild pointer. At line 990, the vulnerable sink executes: CompareMem(DhcpSb->ClientAddressSendOut, Head->ClientHwAddr, Head->HwAddrLen) — with HwAddrLen=255, this can read up to 239 bytes OOB into adjacent heap fields, but the compare returns at the first mismatching byte, so each byte past the array is only read if every earlier byte matched. DhcpValidateOptions at line 1001 runs after the sink and only validates DHCP options, not HwAddrLen.

Affected Callers

  • UdpIoRecvDatagram (registered at Dhcp4Driver.c:318, Dhcp4Io.c:1054, Dhcp4Io.c:1066)

Sanitization / Security Controls

Two controls exist but both are ineffective: - Size check (Dhcp4Io.c:963): Validates only total packet size >= sizeof(EFI_DHCP4_HEADER), not the HwAddrLen field. Ineffective. - DhcpValidateOptions (Dhcp4Io.c:1001): Runs AFTER the vulnerable CompareMem at line 990 and only validates DHCP options (e.g., option 53), not HwAddrLen. Ineffective.

No sanitization points exist on the data flow path.

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

Reproduction

  1. Attacker is on the same network broadcast domain as the target device; target is performing PXE/DHCP network boot with the firmware DHCP client active; no authentication required (DHCP is pre-auth).
  2. Attacker monitors the broadcast domain for DHCP DISCOVER/REQUEST packets from the target.
  3. Attacker crafts a DHCPv4 reply (BOOTP_REPLY) with matching Xid and HwAddrLen set to 255 (0xFF).
  4. Attacker sends the crafted reply via UDP to the target's DHCP port.
  5. Firmware's DhcpInput callback fires; NetbufCopy populates EFI_DHCP4_HEADER with attacker bytes including HwAddrLen=255.
  6. CompareMem compares up to 255 bytes starting at the 16-byte ClientAddressSendOut buffer; with the first 16 bytes of ClientHwAddr matching ClientAddressSendOut (the client hardware address the target sent), it reads past the array into adjacent DHCP_SERVICE heap fields for as long as the attacker's following bytes match them, and the reply is accepted only if all 255 bytes match.

Impact

Out-of-bounds heap read used as a match/no-match oracle. Whether the reply is accepted shows whether the attacker's guessed bytes equal the DHCP_SERVICE fields after ClientAddressSendOut (ActiveChild pointer, ActiveConfig), which lets an on-link attacker recover heap pointer values one byte at a time by raising HwAddrLen by one per guess. A crash is not realistic: leaving the DHCP_SERVICE allocation would require matching every pointer, handle and configuration byte that follows the array. The leaked pointers have little value in firmware without address randomization.

Remediation and Mitigation

As of commit 70741a15d9a714323a5598eac47727e60507e22f this issue is unfixed upstream and no CVE has been assigned. Before reading each field, validate that its full width fits within the remaining bytes derived from the packet or record size, and stop parsing or reject the input when it does not. 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