Public Security Advisories
Coordinated vulnerability disclosures from Argus. Findings, impact, and remediation, published in good faith.
The function PeiUsbGetAllConfiguration parses USB configuration descriptors from a physically connected USB device (EXTERNAL_UNTRUSTED) and uses two fields from the untrusted descriptor as array indices into fixed-size arrays in the page-allocated PEI_USB_DEVICE structure without proper runtime bounds validation.
The DXE-phase function UsbSelectConfig loops (line 412) on the untrusted NumInterfaces field from the USB configuration descriptor and writes a pointer to each newly created USB_INTERFACE into the fixed-size array Device->Interfaces[USB_MAX_INTERFACE] (16 entries, UsbBus.h:45,178) at line 431.
This is a variant of Finding 2.
ReadDirectoryEntry loops over a directory's recorded data, advancing a byte cursor (FidOffset) and casting it to a UDF_FILE_IDENTIFIER_DESCRIPTOR pointer via GET_FID_FROM_ADS (a raw (UINT8*)Data + offset cast).
GetLongAdFromAds loops over a file entry's allocation descriptor sequence, advancing a byte cursor (*Offset) and casting it to a UDF_LONG_ALLOCATION_DESCRIPTOR pointer.
GetShortAdFromAds loops over a file entry's allocation descriptor sequence, advancing a byte cursor (*Offset) and casting it to a UDF_SHORT_ALLOCATION_DESCRIPTOR pointer.
UsbEthNcmReceive parses an attacker-supplied NCM16 Network Transfer Buffer (NTH16 + NDP16 + datagrams) received via USB bulk transfer from a USB CDC-NCM Ethernet adapter.
RndisUndiReceive is the RNDIS implementation of the same EDKII_USB_ETHERNET_PROTOCOL.UsbEthReceive handler interface.
The device-controlled LBA Data Size (Lbads) field — a full UINT8 (0–255) from the NVMe Identify Namespace response — is used directly as the shift amount in (UINT32)1 << Lbads without any bounds validation.
In UsbBusBuildProtocol (whose debug messages are prefixed UsbBusStart), RootHub is allocated at line 1037 (AllocateZeroPool(sizeof(USB_DEVICE))).
In XhcInitSched, three allocations use ASSERT-only guards before dereference.
The 64-bit counterpart of XhcInitializeDeviceSlot.
In XhcInitializeEndpointContext, two EndpointTransferRing allocations have NO NULL CHECK AT ALL (not even ASSERT) before the result is stored and passed to CreateTransferRing which dereferences it.
The 64-byte-context counterpart of XhcInitializeEndpointContext, used when the controller reports Csz != 0 (Xhci.c:1110-1113).
An additional unchecked allocation within XhcInitializeDeviceSlot, next to the unchecked InputContext (line 2246) and EndpointTransferRing (line 2307) allocations in the same function.
In the GET_DESCRIPTOR hook of the XHCI DXE control transfer handler XhcControlTransfer (Xhci.c:1035-1075), three AllocateZeroPool calls have NO NULL CHECK before dereference.
The PEI-phase counterpart of CreateTransferRing.
The PEI-phase counterpart of CreateEventRing.
The PEI-phase counterpart of XhcInitSched.
The PEI-phase counterpart of XhcInitializeDeviceSlot.
The PEI-phase 64-bit counterpart of XhcInitializeDeviceSlot.
The PEI-phase counterpart of XhcInitializeEndpointContext.
The PEI-phase 64-bit counterpart of XhcInitializeEndpointContext64.
In FvIsBeingProcessed, a KNOWN_HANDLE is allocated with AllocatePool(sizeof(KNOWN_HANDLE)) but only guarded by ASSERT(KnownHandle != NULL) — a no-op in RELEASE builds.
In CreateTransferRing, UsbHcAllocateMem (which returns NULL on failure) is called, but only an ASSERT(Buf != NULL) guards the result.
// No embargoed advisories.