On 15 October 2026, the Linux kernel fixed CVE-2026-98432, a use-after-free in the code that handles incoming IPv4 TCP connections. It is rated 9.8 out of 10. An attacker needs no account and no open application bug: the flaw sits in the TCP handshake itself, before any service sees the connection, and it has been in every kernel since version 4.4, released in January 2016.
It went from a line in a changelog to a headline on 27 October, when an AI research lab reported that one of its unreleased models had turned the bug into a working remote root exploit in a lab, with no credentials and no user interaction.
Debian already ships fixed kernels. At the time of writing, Ubuntu does not: its fixes are prepared but not yet published. Below: what the flaw is, who is actually exposed, how to check the kernel you are really running, how to patch, and how to block the trigger on systems that are still waiting for a package.
What the Flaw Actually Is
IPv4 packets can carry options in their header. Two of them, Record Route and Timestamp, ask the receiver to echo information back. When a connection request (a SYN) arrives with one of these options, the kernel stores a copy of them with the half-open connection, and uses it again when it builds the reply (the SYN-ACK).
The bug is a race over who owns that copy. When the handshake completes, the new connection takes over the stored options without duplicating them. If the client retransmits its SYN at the same moment, another CPU can still be building a SYN-ACK from those options while the connection that now owns them is torn down and frees them. The SYN-ACK is then built from freed memory.
Depending on what has reused that memory, the result ranges from a kernel crash, to kernel memory copied into a packet sent back to the attacker, to writes into kernel memory that can be steered. A second variant affects request-socket migration, a feature that is off by default (net.ipv4.tcp_migrate_req).
Affected: every kernel from 4.4 onwards. Fixed upstream in 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10 and 7.3. Kernel lines older than 5.10, including 5.4, get no upstream fix.
Who Is Exposed
The vector is IPv4 TCP: any Linux machine that accepts TCP connections over IPv4 from a network an attacker can reach. That includes services listening on all addresses (::), because IPv4 connections to them take the same path. The service behind the port does not matter, because the bug fires during the handshake, before the application is involved.
- Anything with its own public IP and an open TCP port. SSH, VPN gateways, mail servers, databases exposed for convenience, game and voice servers, Kubernetes API servers.
- Your own reverse proxies and load balancers. If they run Linux and face the internet, they are exactly where the attacker's SYN lands.
- Kubernetes nodes and container hosts. Containers have no kernel of their own. Every pod on a node shares the node's kernel, so rebuilding images changes nothing here.
- Internal systems. Many networks drop packets with IP options at the edge, but an attacker who is already inside, on a compromised workstation or in the same cloud network, is not behind that edge.
What is usually not exposed: a backend that only receives connections from a CDN or a proxy that opens its own connections to it. The attacker's packets end at the proxy, and the backend only ever sees the proxy's SYNs. The proxy itself is a different story if you run it.
How Big This Is
- Ten years of kernels. The affected range starts at 4.4 (January 2016), so practically every Linux server, virtual machine and Kubernetes node in production today is in scope until it is patched and rebooted.
- Every distribution, and not all of them are covered. Fixes landed in eight stable kernel lines. Older lines get nothing upstream, and long-term distributions that still run them depend entirely on their vendor's backport.
- A lab built a zero-click root exploit. On 27 October, an AI research lab reported that one of its unreleased models had built an exploit chain for this bug: it defeated kernel address randomisation remotely in about 48 minutes, then needed about five more to get a root shell. The lab also reported that a lost race only fails the handshake without crashing the machine, so an attacker can keep retrying. Its target was a server listening with Multipath TCP (MPTCP), more on that in Step 3.
The honest caveat: the exploit was built in a lab and has not been released, there are no known attacks in the wild, and the vulnerability is not on the official list of vulnerabilities known to be exploited. The public record describes a plain IPv4 TCP fix, and only the lab's own write-up ties the exploit to this CVE. Some distributions also rate the bug lower than 9.8, because winning the race is harder than the score assumes.
That is a reason to patch on a schedule, not to skip it. The fix is public, so the bug is easy to find, and the lab's result shows the race can be won reliably with enough patience.
Not sure which of your machines accept connections directly from the internet? That is the first question. Request a free Linux kernel exposure assessment and our security team will map it with you.
Step 1: Check the Kernel You Are Actually Running
A kernel update does nothing until the machine reboots into it, so check the running kernel, not the installed packages:
uname -rOn Ubuntu, uname -r hides part of the version. The fixed 22.04 kernel is 5.15.0-203.213, but uname -r only shows 5.15.0-203-generic. The full version is here:
cat /proc/version_signatureOn Debian, uname -v includes the package version. For a fleet, collect the same information from every host, and remember the machines nobody logs into any more.
On Kubernetes, the node list shows each node's kernel in the KERNEL-VERSION column:
kubectl get nodes -o wideInside a container, uname -r reports the host's kernel. That is the one that has to be fixed.
Step 2: Patch and Reboot
Debian has fixed kernels: 6.1.190-1 for 12 (bookworm) and 6.12.113-1 for 13 (trixie).
Ubuntu, at the time of writing (29 October), has fixes prepared but not published. The fixed kernels for 22.04 (5.15.0-203.213), 24.04 (6.8.0-149.149) and 26.04 (7.0.0-43.43) are in the -proposed testing pocket, not yet in the normal updates. Cloud-optimised kernels carry their own version numbers, listed on Ubuntu's page for the CVE. 20.04 and older are listed as vulnerable. The -proposed pocket is for testing, not production: until the packages reach the normal updates, use Step 3.
Other distributions: follow your vendor's advisory for CVE-2026-98432 and compare it with the kernel you actually run.
On Debian and Ubuntu, once the fixed kernel is available:
sudo apt update
sudo apt full-upgrade
sudo rebootUse full-upgrade: a new kernel often arrives as a new package, which a plain upgrade can hold back. If you use a kernel live-patching service, check whether it covers this CVE. If it does not, the reboot is the fix.
On Kubernetes, roll the nodes one at a time so workloads move instead of stopping:
kubectl drain <node> --ignore-daemonsets --delete-emptydir-data
# patch and reboot the node, then:
kubectl uncordon <node>On managed Kubernetes, the fix arrives as a new node image: upgrade the node pools once your provider publishes it.
Step 3: If There Is No Package Yet, Block the Trigger
The first variant needs an IPv4 SYN that carries Record Route or Timestamp options. Legitimate TCP traffic practically never carries IPv4 options, so dropping TCP packets that have them removes the trigger without touching normal connections. This reduces exposure, it does not replace the patch.
With nftables, on the host:
sudo nft add table ip ipopts
sudo nft add chain ip ipopts pre '{ type filter hook prerouting priority -300; }'
sudo nft add rule ip ipopts pre ip protocol tcp ip hdrlength != 5 counter dropA header length of 5 means no options, so anything longer is dropped. The rule sits in the earliest hook, which also covers traffic forwarded to containers and pods on that host. We tested it: SYNs with Record Route or Timestamp options get no reply, and normal connections work as before. It is limited to TCP on purpose. Multicast group management (IGMP) uses an IP option, so a rule that dropped every packet with options would break multicast.
With iptables instead:
sudo iptables -t raw -I PREROUTING -p tcp -m u32 --u32 "0>>24&0xF=6:15" -j DROPTo see how many packets the rule has dropped, or to remove it:
sudo nft list chain ip ipopts pre
sudo nft delete table ip ipoptsRules added this way are lost on reboot. To keep the rule, save it to a file and load it at boot with your configuration management:
# /etc/ipopts.nft (load with: sudo nft -f /etc/ipopts.nft)
table ip ipopts
delete table ip ipopts
table ip ipopts {
chain pre {
type filter hook prerouting priority raw; policy accept;
ip protocol tcp ip hdrlength != 5 counter drop
}
}The first two lines make the file safe to load more than once. Do not add it to a stock /etc/nftables.conf that starts with flush ruleset on a host running Docker or Kubernetes: reloading that file wipes their rules.
Also check two settings.
net.ipv4.tcp_migrate_reqshould be0, the default. That keeps the second variant out of reach unless a program uses the same migration feature through BPF.- Multipath TCP. The lab's exploit targeted an MPTCP listener, and you may have more of those than you think: programs built with Go 1.24 or later listen with MPTCP by default on Linux. We tested it: the same listener is plain TCP with Go 1.23 and MPTCP with Go 1.24 and 1.25. Turning MPTCP off does not fix the bug, but it removes the setup the published exploit used. If you do not need it, set
net.mptcp.enabledto0, or start Go services withGODEBUG=multipathtcp=0, then restart them. The setting only affects new sockets, and it is per network namespace, so check it inside containers too.
sysctl net.ipv4.tcp_migrate_req net.mptcp.enabledStep 4: Watch for Attempts
Do not wait for crashes. A lost race does not have to crash the machine, so a quiet kernel log proves nothing. Watch for the trigger instead. This captures incoming connection requests that carry IPv4 options, and on a normal server it should stay silent:
sudo tcpdump -nni any 'ip[0] & 0xf > 5 and tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn'If you deployed the nftables rule, its counter does the same job permanently. A counter that keeps growing means someone is sending these packets to you.
Crashes still deserve a look when they happen. An unexpected reboot, or a kernel log mentioning skb_under_panic or ip_options_build, on a machine that accepts outside connections, is worth investigating:
# this boot
sudo journalctl -k -b 0 | grep -E 'skb_under_panic|ip_options_build'
# the previous boot, if the journal is persistent
sudo journalctl -k -b -1 | grep -E 'skb_under_panic|ip_options_build'The Real Problem Is the Patch That Needs a Reboot
Most teams have a working routine for packages: images are rebuilt, dependencies updated, scanners turn green. Kernels fall outside it. The fix is installed by the routine updates and then waits for a reboot nobody schedules, on hosts that look patched to every tool that reads package lists.
The useful questions are which kernel each machine is actually running, which machines accept connections straight from the internet, and how long a fixed kernel waits before the reboot that activates it.
Get a Free Linux Kernel Exposure Assessment
If you are not sure which of your servers, nodes or appliances are exposed, or how to cover them until your distribution ships a fix, our security team will work it out with you at no cost.
The free assessment covers:
- An inventory of the kernels you actually run across hosts, virtual machines and Kubernetes nodes, checked against the fixed versions for your distribution, not against the installed packages
- A map of what accepts connections directly from the internet or from untrusted networks, including the hosts behind your proxies and load balancers
- A prioritised plan for the period before a fix ships: where to block the trigger, where to switch off MPTCP, and how to schedule the reboots without downtime
You get a written list of what is exposed and what to do about it, with no obligation attached.
Request your free Linux kernel exposure assessment, or read more about our Linux consulting, Kubernetes consulting and cybersecurity practice. The same "check what is really running" rule applied to the Brotli flaw last week.