Linux kernel CVE-2026-99999: A deferred checksum overwrites the already validated IPv4 header
When a network card can compute checksums itself, the Linux kernel postpones that work and only remembers where the calculation starts and where the result should be written. With virtio-net, both values come from the guest, and that is the core of CVE-2026-99999. If the start value points into an IPv4 header the host has already validated, the deferred checksum overwrites the header length there. The fragmentation code in ip_do_fragment() then relies on the altered value and copies host memory into outgoing packets. Paulos Yibelo, who found the flaw, used this to demonstrate a memory leak in Vercel's production sandboxes and, in his own lab, got as far as host crashes and root on KVM and Firecracker hosts.
TL;DR — 90 seconds
- What: The kernel accepts checksum metadata (
csum_start,csum_offset) from virtio-net, TUN and packet sockets. Before completing the deferred calculation, it did not check whether the start value lies behind the IPv4 header, soskb_checksum_help()could overwrite the already validated header. - Severity: The kernel CNA scores it CVSS 9.3 (
AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H), Red Hat and Amazon Linux 8.8. Since 17 October several unverified repositories relating to the CVE have appeared, no confirmed exploit is known, and the flaw is not in the CISA KEV catalog. - Who is affected: First and foremost Linux hosts running untrusted guests over virtio-net, i.e. your own KVM, QEMU or Firecracker hosts, sandbox platforms and CI runners with microVMs. Local paths via TUN and packet sockets exist in the code but have not been demonstrated for ordinary container nodes.
- What to do: Install a kernel with commit
6785011f8b16or your distribution's backport and reboot. Upstream, the fix is in 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.57 and 7.2.11, as well as in Linux 7.3 from 18 October. Amazon Linux and Debian have their own package versions. - What would have protected you beforehand: Not offering checksum offload to untrusted guests, running pods with the
RuntimeDefaultseccomp profile, and disabling unprivileged user namespaces where nobody needs them. Image scans and firewall rules do not help against this mechanism.
Deferred checksums and a header that is read twice
Checksums cost CPU time, which is why operating systems like to leave their calculation to the network card. The kernel documentation describes how this works on Linux. The network stack marks an outgoing packet as CHECKSUM_PARTIAL and records in two fields from which position the checksum is computed to the end of the packet (csum_start) and where the result goes (csum_start + csum_offset). If the device cannot do the calculation, the kernel catches up in software with skb_checksum_help(). So the calculation happens late, while the decision about where the result is written was made early. In between, other parts of the stack work with the same packet.
In virtualised networks, both fields come from the guest. A virtio-net device puts a small header in front of every packet in which the guest requests the offload. Whether it may do so is governed by the VIRTIO_NET_F_CSUM feature, described in the kernel header as “Host handles pkts w/ partial csum”. How the packet reaches the host is described very concretely in the CVE record: the VMM writes the guest's frame into a TAP device, and tun_get_user() hands it, metadata included, to the IPv4 stack. At its core, the VM path and the TUN path are therefore the same. Packet sockets accept the virtio header as well, and these two entry points are exactly what the fix names as its origin: “tun: Allow GSO using virtio_net_hdr” and “packet: Add GSO/csum offload support”. According to the CVE record, the affected range goes back to Linux 2.6.27.
This is where the bug was. On input, the kernel did check whether csum_start was too far forward, but according to the researcher's analysis it did so relative to the current view of the buffer and not relative to the IPv4 header. If the packet contains additional link-layer structure, a cleverly chosen start value passes this check and still points right into the IPv4 header. The host then reads the header quite normally, finds the value 5 in the IHL field, meaning 20 bytes, and treats the packet as validated.
Why this becomes dangerous is shown by ip_do_fragment() in net/ipv4/ip_output.c. When a packet has to be split up on its way out, the function first called skb_checksum_help() and only then read the IPv4 header and its length. The deferred checksum landed where the guest wanted it, in the researcher's case on the byte holding version and IHL. 5 became 15, and from then on the header counted as 60 bytes long. When building the fragments, the kernel therefore copied 60 bytes as header, although only 28 bytes of valid data sat in the linear part of the buffer. The remaining 32 bytes came from adjacent host memory and left the host as supposed IP options.
The researcher sums up the pattern in one sentence: different parts of Linux were allowed to trust different versions of the same packet. I consider this the real core of the case. Each of the two checks was reasonable on its own; they just referred to different points in time. Between check and use there was a write whose target a less trusted sender had chosen. It is the familiar time-of-check-to-time-of-use problem, except that this time it occurs between two layers of the same kernel rather than between two processes.
What the fix commit changes
Commit 6785011f8b16 by Michael S. Tsirkin is titled “ipv4: validate checksum_start before completing checksum”. It was taken into net.git on 8 October and into mainline on 14 October and changes six files. In include/net/ip.h it adds the helper ip_check_csum_start(), which reports an error as soon as csum_start lies before the end of the IPv4 header. The end is defined as the position of the network header plus its actual length. This check now runs before skb_checksum_help() wherever an IPv4 packet with a pending checksum is completed. There are five such places: ip_do_fragment(), fragmentation in bridge conntrack (nf_br_ip_fragment()), the NFQUEUE checksum helper, the iptables CHECKSUM target and xfrm_output() for IPsec. If it fails, the kernel drops the packet instead of writing the checksum.
Where the commit intervenes is revealing. It secures the places where the checksum is written and leaves the check on incoming packets as it is for now. The commit message says so openly: such packets should not get in at all, the new check is defence in depth, and a more complete validation at input still needs work. According to the researcher, the review revolved around whether a broad check in a central helper or targeted checks at each of these places carry more risk, because nested headers, IP options and IPv6 are hard to capture with a simple fixed boundary. The fix is also limited to IPv4. For IPv6, neither a leak nor privilege escalation has been shown, and it explicitly does not cover the researchers' further concerns about transport fields changed later on. With the patch you close the proven flaw, but the class of bugs behind it remains open.
From guest packet to host memory: prerequisites and impact
The CVE record describes the starting point as a malicious microVM sending crafted packets over its virtio-net interface. Nothing more is needed. According to the record, the guest needs neither credentials nor capabilities on the host, and anyone renting a VM or allowed to run code in a sandbox has root in their own guest kernel. Affected out of the box is therefore any unpatched Linux host that offers guests a virtio-net device with checksum offload and sends their packets through its own IP stack, typically via a TAP device with a bridge or NAT. According to the libvirt documentation, QEMU enables the supported offloads by default, and according to its source code Firecracker always offers VIRTIO_NET_F_CSUM. Whether a specific host runs through the affected functions depends, as the researcher states, on network implementation, kernel version and configuration. Hosts that route guest packets past the kernel stack via vhost-user, DPDK or SR-IOV are, in my reading, outside the core scope.
Conceptually, the attack chain is short. The guest sends a packet whose offload metadata points at the IPv4 header and makes sure the host has to fragment it. The host validates the header, then writes the checksum into it and, while fragmenting, copies 32 bytes of its own memory into the outgoing packet. At Vercel, these bytes ended up in packets the guest sent to the internet, for as long as it kept sending. According to Vercel, two packets were enough to crash a host and thereby end every sandbox on it. On his own KVM and Firecracker systems in Vercel's configuration, the researcher also achieved targeted 64-byte writes into the host kernel and commands with root privileges on the host. He is holding back the details of this write chain for a second part.
This weighs heaviest where many tenants share a host. A crash hits every VM on that kernel, leaked memory can contain other guests' keys or tokens, and with root on the host any tenant separation is void. Vercel stresses that no customer files, secrets or application data were exposed during the challenge.
Equally important is who only believes they are affected. For EC2, Lambda and Fargate, AWS bulletin 2026-137-AWS makes clear that the infrastructure operated by AWS is not affected and nothing needs to be done there. That only covers the layer beneath your instance, though. The kernel inside the instance contains the flaw too, and as soon as you run your own VMs on it, it is an affected host like any other. For Kubernetes nodes without VMs, the situation is less clear-cut. CloudLinux considers local paths via TUN in an unprivileged user namespace and via packet sockets plausible from the code, but could trigger neither a kernel oops nor a KASAN report in its own tests. I therefore classify container nodes as possibly affected, with considerably less urgency than hosts running untrusted VMs. Whether a container on an ordinary node actually reaches the host's fragmentation path is not publicly established.
| CVE | Affected | Fix | Prerequisite | CVSS |
|---|---|---|---|---|
| CVE-2026-99999 (PwnEscape) | Linux kernel from 2.6.27, stable branches before 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.57 and 7.2.11 | Commit 6785011f8b16 and stable backports, mainline from 7.3-rc7 and therefore in the final Linux 7.3 | Packets with self-chosen offload metadata via virtio-net, TUN or packet socket that the host stack fragments or processes via NFQUEUE, the CHECKSUM target or IPsec | 9.3 (critical, kernel CNA), 8.8 (Red Hat, Amazon Linux) |
None of the primary sources names a public proof of concept, and CloudLinux stated explicitly that none exists. Since 17 October, however, eight repositories from six authors relating to this CVE have appeared on GitHub. The two I looked at are a scanner and an unverified proof of concept that, by its own description, reproduces the memory leak and a KASLR bypass, but not the privilege escalation. So there is still no confirmed exploit to root, but the mechanism is drawing a lot of attention. The researcher has not yet published the second part of his analysis. The flaw is not in the CISA KEV catalog, and in the SSVC assessment attached to the CVE record CISA rates exploitation as “none”. EPSS estimates the probability of exploitation in the next 30 days at 0.21 percent. For operators of sandbox platforms I consider this figure set too low, because the mechanism is publicly described, the fix points to the affected places, and the second part with the write chain has been announced.
Kernel fix, backports and the reboot that goes with them
Only a kernel with the fix protects fully against the proven flaw, and only once the host has rebooted into it. Upstream, commit 6785011f8b16 is in the stable releases 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.57 and 7.2.11, and Linux 7.3, released on 18 October, contains it as well. Distributions backport the fix into their own kernels, whose version numbers are often below the upstream version with the fix. Comparing only against the upstream list therefore easily leads to wrong conclusions. What counts is your distribution's advisory.
For Amazon Linux, the AWS bulletin names the first kernels with the fix. On Amazon Linux 2 these are 4.14.355-287.750.amzn2, 5.4.302-229.494.amzn2, 5.10.269-270.1108.amzn2 and 5.15.220-156.256.amzn2. On Amazon Linux 2023 they are kernel 6.1.188-233.385.amzn2023, kernel6.12 6.12.110-135.201.amzn2023 and kernel6.18 6.18.51-120.162.amzn2023. The Amazon Linux Security Center lists all packages as Fixed, for Amazon Linux 2 under ALAS2-2026-3962, ALAS2KERNEL-5.4-2026-131, ALAS2KERNEL-5.10-2026-133 and ALAS2KERNEL-5.15-2026-117, for Amazon Linux 2023 under ALAS2023-2026-3197, ALAS2023-2026-3196 and ALAS2023-2026-3192. AWS advises operators of their own virtio-net and KVM hosts to install the packages and reboot, and explicitly names no workaround.
Debian has shipped the fix for Bookworm with linux 6.1.190-1 (DLA-4841-1) and for Trixie with 6.12.113-1 (DSA-6568-1). Red Hat rates the flaw Important, lists all supported product streams as affected and, according to its CVE page, is still working on fixes. Wolfi is not directly affected, because container images do not bring their own kernel and always use the host's.
The fix changes no configuration and only affects packets whose metadata points into the IPv4 header. The kernel now drops these, and they should not occur in regular operation. The real pitfall is organisational. An installed but not booted kernel package does not protect you, and on hosts with many guests the reboot is the expensive part. On virtualisation hosts you therefore first move the guests to patched machines or shut them down in a planned way, reboot, and then check the running kernel. Kubernetes nodes are best replaced rather than updated in place, for example with a new AMI for the node group that replaces the nodes one after another. According to CloudLinux, livepatches such as KernelCare are rolling out right now. They only spare you the reboot if your vendor actually ships the patch for your kernel.
Hardening beyond the patch: offload, capabilities and namespaces
Before looking at individual measures, it is worth asking what can work against this mechanism at all. The bug sits in the host kernel and is triggered by values that a less trusted sender writes into a packet buffer. Neither a container image nor a firewall rule nor a hardened application inside the guest changes anything about that. What works is anything that closes one of the entry points through which such metadata gets in: the offload of virtio-net, TUN and packet sockets with a virtio header. On top of that comes everything that limits the damage should someone reach the host kernel anyway. CloudLinux rightly points out that each of these measures removes only one prerequisite and none replaces the kernel fix.
No checksum offload for untrusted guests
The guest can only dictate csum_start because the host offers it checksum offload. Without VIRTIO_NET_F_CSUM, the guest has to send complete checksums, and the proven attack loses its foundation. Under libvirt with QEMU, you control the host offloads via the <host> element in the network interface's <driver> block. The example in the libvirt documentation sets csum to off there together with the segmentation offloads gso, tso4, tso6, ecn and ufo. CloudLinux names this measure as partial protection and lists its limits right away. It is set per VM, needs a guest restart, costs throughput and has not yet been tested against this exact flaw. With Firecracker this lever does not exist. According to its source code, the virtio-net device sets VIRTIO_NET_F_CSUM unconditionally, and I see no setting to turn it off. Firecracker hosts are therefore left with the kernel fix alone. Where you use QEMU, by contrast, disabling the offload is the measure that targets the mechanism most directly until every host is patched.
The RuntimeDefault seccomp profile and Pod Security “restricted”
On container nodes, the local path CloudLinux describes runs through a user namespace of one's own. Whoever creates one gets, according to user_namespaces(7), the full set of capabilities inside it, and with a network namespace of its own on top, the process may create network devices such as TUN there, regardless of what the container was given from outside. This is where containerd's default profile comes in. In the current 1.7 and 2.1 releases it allows unshare and setns only for containers with CAP_SYS_ADMIN, and without that capability it permits clone only if none of the flags for new namespaces is set, CLONE_NEWUSER included. An ordinary container therefore gets neither its own user namespace nor its own network namespace. I derive this from the profile's source code; the researchers did not test it.
Kubernetes does not apply the profile on its own, however. Without a setting, a container runs as Unconfined according to the Kubernetes documentation, unless the kubelet runs with --seccomp-default or seccompDefault: true in its configuration. So set seccompProfile.type: RuntimeDefault in the pod or enable the default in the kubelet. The easiest way to enforce this is the built-in Pod Security Admission. The label pod-security.kubernetes.io/enforce: restricted on a namespace rejects every pod that sets no seccomp profile or does not request capabilities.drop: ["ALL"]. As a result, a pod also gets no CAP_NET_ADMIN, which according to the kernel documentation is required to create network devices. Exceptions are usually only needed for CNI and storage components in system namespaces, and you record those deliberately.
Unprivileged user namespaces on hosts with untrusted code
On hosts where people or pipelines run code directly and without containers, such as CI runners with a shell executor or build servers, this seccomp barrier does not exist. There the local path runs unhindered through the user namespace. How many of these a user may create is governed by /proc/sys/user/max_user_namespaces, and CloudLinux names user.max_user_namespaces=0 as a partial measure. The price is high. According to namespaces(7) the limit applies to all users including UID 0, so it breaks rootless containers, the Chrome and Flatpak sandboxes and also Kubernetes pods with hostUsers: false. Against the VM path the switch does nothing. It makes sense on dedicated runner and build hosts where you know for certain that none of this runs.
Planning sandbox hosts as if the kernel will fall
If you run untrusted code in VMs, you should assume this was not the last flaw of its kind. Vercel draws exactly this conclusion from the challenge and names stronger per-sandbox protections, up-to-date host kernels, disabled nested virtualisation and Firecracker's jailer, which restricts every microVM process. I consider the jailer the right call, but it constrains the VMM process and not the host kernel, so it does not work directly against this bug. Clear separation achieves more. Hosts running untrusted code then hold no secrets of other systems, no cluster credentials and no sensitive workloads, so a memory leak finds little there. Egress rules for sandboxes additionally make it harder to carry leaked bytes away, but do not reliably prevent it as long as the guest may send outward at all.
What does not help here
Image scanners and minimal base images such as Wolfi or distroless miss this flaw entirely, because the vulnerable code lives in the host kernel and appears in no image. A CVE gate in the image pipeline therefore does not trigger. Host scanners only detect the flaw reliably if they know the distribution's backports and check the running kernel rather than the installed package.
NetworkPolicies and firewall rules filter by addresses and ports, but the bug lies in processing a packet the host accepts anyway. None of the analyses checked knows a rule that catches it. Disabling offloads on the host's physical network card is not a proven remedy either, because the metadata comes from the guest and not from the card. Hardening inside the guest achieves nothing on the VM path, because the attacker is root there anyway, and readOnlyRootFilesystem plays no role, because the attack writes no files.
You will find more on Pod Security, seccomp profiles and separating workloads in the series TYPO3 on Kubernetes under IT-Grundschutz.
Detection and verification
Whether a host is affected is decided by the running kernel that uname -r shows, not by the most recently installed package. Compare it with your distribution's advisory, and for Amazon Linux with the versions from the AWS bulletin. Next comes the question of how exposed the host is. If it runs VMs with virtio-net whose content you do not control, it has top priority. On Kubernetes nodes, what matters is which pods still carry additional capabilities such as NET_ADMIN, run privileged or start without a seccomp profile. Namespaces without the label for “restricted” are the quickest way into that list.
Harder is the question of whether the flaw has already been exploited. Neither the kernel developers nor AWS, Vercel or the researcher name any IoCs. Two hints follow from the mechanism; I derive them myself and they are not vendor guidance. For one, the researcher demonstrated host crashes with just a few packets, so unexplained kernel oopses or reboots on hosts with untrusted guests deserve a second look. For another, during the memory leak the fragments carry a 60-byte IPv4 header with supposed options. IP options are rare in normal traffic, and a capture of outgoing guest traffic that looks for fragments with IHL 15 can reveal anomalies. An unremarkable result proves little, though, because the leak is quiet.
If you suspect an attack, treat the host's memory as exposed. Move the guests to patched hosts, reboot the host into the new kernel and rotate everything that sat in its memory, i.e. its own credentials, other guests' keys and tokens of agents or kubelets. If root access is suspected, rebuild the host instead of repairing it.
Recommendation for operators
Act now if your Linux hosts run VMs whose content you do not control. That applies to sandbox platforms for code or AI agents as much as to CI runners with Firecracker or QEMU guests, KubeVirt or Kata Containers with untrusted workloads, and VMs rented out on your own hardware. Install your distribution's kernel with the fix, reboot and check the running kernel. Until then, take checksum offload away from untrusted guests under QEMU and keep sensitive workloads off these hosts.
Monitoring is enough if no untrusted VMs run on your hosts, for example EKS nodes or k3s servers with your own workloads whose pods run with RuntimeDefault and under “restricted”. The kernel update then belongs in the next regular maintenance window. Until then it is worth checking which pods still run without a seccomp profile, because changing that helps far beyond this flaw.
Regardless of the individual case, what I say about every flaw applies: patches and updates belong in automation, and for kernel flaws that applies to nodes as much as to packages. When Renovate or Dependabot propose new AMI IDs, operating system versions and Helm charts as merge requests on their own and the pipeline first rehearses the node replacement in a staging cluster, a kernel fix like this one is a matter of hours rather than weeks. A cooldown period for routine updates protects you from compromised releases, and you exempt security updates from it. If a new kernel does bring a break, for example because an unusual network configuration suddenly loses packets, it shows up in testing and not in production. Updating hosts by hand, on the other hand, quickly means weeks without a patch during the holiday season, followed by one big batch reboot where a lot can go wrong at once.
Frequently asked questions about CVE-2026-99999
Does this affect my EC2 instances or EKS nodes?+
According to AWS, the layer it operates beneath EC2, Lambda and Fargate is not affected. The kernel inside your instance does contain the flaw, though. Install the kernel update per ALAS, and do so immediately if untrusted VMs run on it.
Is rebuilding my container images enough?+
No. The flaw sits in the host's kernel, and no image brings that along. You need to reboot the host or node into a patched kernel.
Does the Pod Security Standard restricted help?+
It requires a seccomp profile and strips all additional capabilities from pods. That closes the local path via own namespaces inside the container. It does not help against untrusted VMs on the host.
Is there a workaround without a reboot?+
AWS names none. A livepatch only helps if your vendor ships it for your kernel. Until then, take checksum offload away from untrusted guests under QEMU and set the RuntimeDefault seccomp profile for your pods.
Conclusion
PwnEscape is neither a bug in KVM nor one in Firecracker. It is a bug about how long a check stays valid. The host validated the IPv4 header, then allowed a write whose target the guest had chosen, and afterwards relied on the validated value again. The lesson reaches far beyond the network stack. Metadata supplied by a less trusted party is input like any other, even when it seemingly only determines where a calculation happens later. And a validation is only worth as much as the span between check and use during which nobody may write anymore. How long such assumptions can survive in the kernel was already shown in the summer by GhostLock. For operations, two things follow: roll out kernel updates quickly and automatically, and leave every workload only the paths into the kernel it really needs.
Sources
- pwn.ai: PwnEscape, Guest-to-Host KVM Escape (CVE-2026-99999)
- Linux fix commit 6785011f8b16: ipv4: validate checksum_start before completing checksum
- CVE record CVE-2026-99999 (kernel CNA, incl. CVSS rationale)
- NVD: CVE-2026-99999
- FIRST: EPSS
- Vercel: Findings from the 1 million dollar Vercel Sandbox Challenge
- AWS Security Bulletin 2026-137-AWS
- Amazon Linux Security Center: CVE-2026-99999
- Debian Security Tracker: CVE-2026-99999
- Red Hat: CVE-2026-99999
- CloudLinux: CVE-2026-99999 guest-to-host escape
- Kernel docs: Checksum Offloads
- Kernel docs: TUN/TAP
- libvirt: Domain XML format, NIC driver-specific options
- Firecracker: virtio-net device (feature bits)
- man7: user_namespaces(7)
- man7: namespaces(7)
- containerd 2.1.4: default seccomp profile
- Kubernetes docs: Pod Security Standards
- Kubernetes docs: seccomp
I check your hosts and Kubernetes nodes for unpatched kernels, strip unnecessary capabilities from your pods and build kernel updates with node replacement into your pipeline.
Kernel patch management for Amazon Linux and Kubernetes nodes, Pod Security and seccomp profiles, hardening of sandbox and CI hosts that run untrusted code.
Platform operations instead of consulting on paper: I continuously check, patch and harden your infrastructure.
About the author

Kai Ole Hartwig
Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.
