EDK II - Out-of-Bounds Read in UsbEthNcmReceive
UsbEthNcmReceive parses an attacker-supplied NCM16 Network Transfer Buffer (NTH16 + NDP16 + datagrams) received via USB bulk transfer from a USB CDC-NCM Ethernet adapter.
- Advisory
- BYTERAY-2026-0285
- CWE
- CWE-125, CWE-129, CWE-20
- 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 MdeModulePkg/Bus/Usb/UsbNetwork/UsbCdcNcm/UsbNcmFunction.c.
- Credit
- Argus-Systems
Executive Summary
UsbEthNcmReceive parses an attacker-supplied NCM16 Network Transfer Buffer (NTH16 + NDP16 + datagrams) received via USB bulk transfer from a USB CDC-NCM Ethernet adapter. In the datagram copy loop (lines 283–287) and single-datagram paths (lines 295, 308), the source pointer for CopyMem is computed as BulkBuffer + Datagram->DatagramIndex, where Datagram->DatagramIndex is a 16-bit field taken directly from the attacker-controlled NDP16 datagram table with no bounds validation against the actual received data length (BulkDataLength) or the 65535-byte BulkBuffer allocation. No NTH16/NDP16 signature (magic) validation is performed on the receive path, so all header fields are fully attacker-controlled. Additionally, Ndp->Length (line 272) is used to compute TotalDatagram via (Ndp->Length - 8) / 4 - 1, which underflows when Length < 8 and, after the (UINT8) cast, yields up to 255 datagram entries, amplifying the exposure. Nth->NdpIndex (line 270) is also unchecked, so with NdpIndex up to 0xFFFF the NDP16 header and datagram table themselves are read past the end of BulkBuffer. Together, DatagramIndex + DatagramLength let the copy read up to about 128 KB from the start of the 64 KB buffer.
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 (
MdeModulePkg) - Affected commit:
70741a15d9a714323a5598eac47727e60507e22f(master, 2026-06-21). The code is present on that commit and later revisions that have not changed it. - Location:
MdeModulePkg/Bus/Usb/UsbNetwork/UsbCdcNcm/UsbNcmFunction.c:284 - Function:
UsbEthNcmReceive - Category:
CWE-125/129/20 — Out-of-bounds read via unchecked mapping-table index
Technical Details
Controllability: EXTERNAL_UNTRUSTED — confidence: high
Data Flow
The BulkBuffer is allocated as 65535 bytes via AllocateZeroPool(USB_NCM_MAX_NTB_SIZE) at UsbCdcNcm.c:393. USB bulk transfer at UsbNcmFunction.c:257 fills this buffer with an attacker-controlled NCM16 NTB. At lines 269–272, Nth->NdpIndex derives the Ndp pointer unchecked, and Ndp->Length computes TotalDatagram with an underflow hazard. No NTH16/NDP16 signature validation occurs on the receive path. At line 284, CopyMem reads from BulkBuffer + Datagram->DatagramIndex for Datagram->DatagramLength bytes, with both fields being attacker-controlled 16-bit values and no bounds check against BulkDataLength, causing an out-of-bounds heap read.
Affected Callers
PxeFunction.c:UndiReceive(Nic->UsbEth->UsbEthReceive→UsbEthNcmReceive)
Sanitization / Security Controls
Three controls were identified, all ineffective:
EFI_ERROR(Status)check onUsbBulkTransfer(line 265–267): Only verifies USB protocol-level success. A malicious device returns a valid transfer containing a crafted payload.TotalLength < USB_ETHERNET_FRAME_SIZEcheck (line 279): Only gates multi-datagram vs. single-datagram copy path. Does not validateDatagramIndexorDatagramLength. The vulnerableCopyMemexecutes regardless of branch taken.- NTH16/NDP16 signature validation: Absent on the receive path entirely (only performed on transmit).
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
- Attacker connects a malicious USB CDC-NCM adapter to the target.
- During PXE boot, the firmware calls
UsbEthNcmReceive. - The adapter responds with a crafted NCM16 NTB where
NdpIndexpoints to a valid in-buffer location,NDP16.Lengthproduces a validTotalDatagram, and one or more datagram entries haveDatagramIndex/DatagramLengthexceeding actual received data. CopyMemreads out-of-bounds heap memory using attacker-controlled offset and length.- OOB data is copied into the
Packetbuffer and returned up the network stack.
Impact
Out-of-bounds heap read of up to about 64 KB past BulkBuffer. The over-read bytes are copied into the receive buffer and handed to the firmware network stack as frame data, and the read causes a denial of service if it extends into unmapped memory. Requires physical attachment of a malicious USB CDC-NCM device; no write past an allocation is reachable through this copy, since the destination ReceiveBuffer comes from an allocation of sizeof (NIC_DEVICE) + BulkDataSize + 4096 with BulkDataSize = 0xFFFF (DriverBinding.c:211, UsbNcmFunction.c:580).
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. Validate the array index against the number of elements before using it to read or write the array. 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.