A week ago I wrote about how PHP2Shell came out early and forced people to mitigate without a patch. Now something similar has happened one level further down, in the firmware that boots servers. TianoCore has published a critical security advisory for EDK II, the UEFI reference implementation that nearly every firmware vendor builds on: AMI, Insyde, Phoenix and also Project Mu, Microsoft’s fork.
The bug, CVE-2026-97631, allows code execution before the operating system starts, by sending an ICMP packet to a machine while it’s network booting.
What PXE boot is
PXE is the mechanism that lets a machine boot by downloading what it needs from the network instead of from its disk. It’s very common in data centres: for installing systems on many machines at once, for diskless servers or for recovery. In EDK II it’s implemented by the NetworkPkg/UefiPxeBcDxe driver.
While the network boot lasts, that driver keeps a receive open for ICMP error messages and copies each one into a 504-byte field in its internal structure. That’s where the problem is.
The bug, in a few lines of C
The original code copied the message fragment by fragment like this:
CopiedLen = 0;
IcmpError = (UINT8 *)&Mode->IcmpError;
for (Index = 0; Index < RxData->FragmentCount; Index++) {
CopiedLen += RxData->FragmentTable[Index].FragmentLength;
if (CopiedLen <= sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR)) {
CopyMem (IcmpError, RxData->FragmentTable[Index].FragmentBuffer,
RxData->FragmentTable[Index].FragmentLength);
} else {
CopyMem (IcmpError, RxData->FragmentTable[Index].FragmentBuffer,
CopiedLen - sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
}
IcmpError += CopiedLen;
}
It has two mistakes. The worst is in the last line: the destination pointer advances by the running total (CopiedLen) instead of the length of the fragment just copied. And once the field size is exceeded, instead of stopping, it keeps copying bytes. With a three-fragment message of 200 bytes each it’s easy to see:
| Fragment | CopiedLen | Copied at offset | Bytes copied | Within the 504? |
|---|---|---|---|---|
| 1 | 200 | 0 | 200 | Yes |
| 2 | 400 | 200 | 200 | Yes |
| 3 | 600 | 600 | 96 | No, writes from byte 600 onwards |
The third fragment is written entirely outside the field, with bytes the attacker chooses. Nothing earlier in the receive path limits the message length. The bug is duplicated in both the IPv4 and IPv6 handlers.
The fix, merged into EDK II’s main branch on 15 October, clears the field, trims each fragment to the remaining space and advances the pointer only by what was copied:
ZeroMem (&Mode->IcmpError, sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
for (Index = 0, IcmpError = (UINT8 *)&Mode->IcmpError, CopiedLen = 0;
(Index < RxData->FragmentCount) &&
(CopiedLen < sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));
Index++, IcmpError += FragmentLen, CopiedLen += FragmentLen)
{
FragmentLen = MIN (
RxData->FragmentTable[Index].FragmentLength,
(UINT32)(sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR) - CopiedLen)
);
CopyMem (IcmpError, RxData->FragmentTable[Index].FragmentBuffer, FragmentLen);
}
The patch also adds GoogleTest tests that check exactly the multi-fragment case.
What an attacker can do
According to the advisory, all it takes is sending a unicast ICMP error message to the machine’s IP while it’s network booting, from any network distance and without authentication. There are two levels:
- Denial of service: the corruption triggers an exception and the boot hangs. It’s deterministic.
- Code execution: if the attacker knows the exact firmware build, they can plant a fake event in the same packet that the firmware ends up running in ring 0, in the DXE phase, before any operating system security control exists and before Secure Boot or measured boot have verified anything.
HD Moore, creator of Metasploit, told Ars Technica that at that point the boot still has access to sensitive components like the TPM, which could be used to break disk encryption. Ars also reports that the bug has been in the code for about 16 years.
Why it isn’t as bad as it sounds, and why it is
There are important limitations, worth being clear about before getting alarmed:
- It only matters while the machine is network booting. A machine that boots from its disk isn’t exposed. That rules out most home and small office users.
- The attacker has to reach the machine with ICMP in that window, which in practice usually means already being inside the network.
- The exploit isn’t universal. Jesse Michael, from Eclypsium, points out that it has to be tailored to each model, version and configuration, because memory addresses change.
- The fix is simple. Unlike bugs such as BootHole or BlackLotus, there’s no need to revoke keys or touch Secure Boot databases: a firmware update is enough.
But there are other reasons to take it seriously. EDK II underpins nearly all server firmware, so the number of affected machines is huge, and updating firmware across thousands of models depends on each vendor and tends to be slow. Moore thinks it will be a “forever” bug on machines no longer supported. And in data centres, which is exactly where PXE is used most, someone already inside the network can use it to compromise machines below the operating system.
The disclosure that came early
It was found by Alex Matrosov, from Anthropic, and Dan Holmes-Mitra, from Google, who had agreed to keep it secret until a coordinated disclosure planned for January. But according to Ars Technica, in September a pull request from an AMI developer appeared in the public EDK II repository with the fix and a description of the bug. Once it was spotted, TianoCore published the advisory on 22 October.
With the patch public, working out how to trigger the bug is immediate, as the table above shows. It’s the same situation as with PHP2Shell: the problem isn’t so much that the patch gets published, but that it’s published before those affected have anything to install.
What to do
At the time of writing, vendor information is scarce: Intel says none of its products under security support are affected, but that a board maker might have integrated the code; Arm says it doesn’t apply directly to its products; and AMD, Phoenix, AMI, Microsoft and Amazon hadn’t answered Ars. Given that, the sensible thing is:
- Ask your server vendor for a firmware update that includes the fix, and apply it when it exists.
- Disable network boot on machines that don’t need it. Many servers have it enabled by default even if they never boot that way.
- Isolate the provisioning network where PXE is used, so only the machines that need to can reach those servers.
- Keep Secure Boot and the TPM enabled, even though they don’t protect against this bug, and watch the logs.
My takeaway
What strikes me is that this bug survived years of fuzzing. After PixieFail, another set of bugs in the same EDK II PXE code, there were several projects dedicated to finding more, and EDK II is even in OSS-Fuzz. And yet a bug that fits in a three-row table was still there. It fits with what I wrote in the post on formal verification with LLMs: fuzzing finds a lot, but doesn’t guarantee it has tried everything.
It also leaves me with the feeling that the same pattern keeps repeating these weeks: serious bugs in years-old code and coordinated disclosures that break early. For anyone running servers, the practical consequence is the usual one, but increasingly urgent: know what you have, what firmware each machine runs and which services it has enabled even if it doesn’t use them.
Source: Pre-boot RCE in EDK II PXE driver, TianoCore, and Code-execution flaw in UEFI firmware affects most servers on planet Earth, Dan Goodin, Ars Technica.




