Skip to main content
November 2, 202610 min read

Linux TCP Remote Root Flaw CVE-2026-98432 and How to Block It

Get technical support

Patched, monitored, restored on a schedule

A 9.8 Linux kernel flaw in the TCP handshake is fixed upstream and in Debian, while Ubuntu and RHEL kernels are still on the way. One tested firewall rule closes the gap today. Here is how to check your servers, apply it and remove it after the patch.

On October 15, 2026, the Linux kernel team published CVE-2026-98432, a use-after-free in the code that handles the start of every IPv4 TCP connection. The kernel's own scoring puts it at 9.8, because a remote machine with no login can reach it by sending crafted connection requests to any listening service. On October 27 Anthropic described a working remote root exploit for it, written by its Claude model in a lab.

The fix is small and it has already shipped. It reached the upstream stable kernels on October 11 and 15, and Debian has packaged it. Ubuntu and Red Hat are still preparing their kernels. For servers on those systems, Red Hat has published a firewall rule that removes the way in until the new kernel arrives. We tested it before writing this, and it does exactly what it says.

Where the Fix Stands on November 2

PlatformStatusFixed in
Upstream stable kernelsFixed7.2.10, 6.18.56, 6.12.113, 6.6.159, 6.1.190, 5.15.223, 5.10.272
Debian 13 trixieFixed, DSA-6568-1linux 6.12.113-1
Debian 12 bookwormFixed, DLA-4841-1 and DLA-4850-1linux 6.1.190-1, linux-6.12 6.12.113-1~deb12u1
Ubuntu 16.04 to 26.10Vulnerable, fix in progressNot released yet
RHEL 8, 9 and 10Rated Critical, fix in progressNot released yet, stopgap in RHSB-2026-016

Ubuntu's tracker already names the kernel builds it is preparing, for example 6.8.0-149 for 24.04 and 5.15.0-203 for 22.04, and the same work covers the AWS, Google Cloud and Azure kernels. Red Hat lists OpenShift and other products built on the RHEL kernel as potentially affected too.

There is no sign of attacks. The flaw is not in CISA's catalogue of exploited vulnerabilities, and Anthropic has not released its exploit. That leaves time to do this properly, one server group at a time.

What the Bug Is, in Plain Terms

A TCP connection starts with a short exchange. The client sends a SYN, the server answers with a SYN-ACK, and the client confirms. A SYN can carry IPv4 options such as Record Route or Timestamp, which ordinary traffic almost never uses today. When one does, the kernel keeps those options with the half-open connection.

The bug is a race. When the connection completes, the kernel hands the stored options to the new socket and later frees them. If the client sends the same SYN again at the right moment, another CPU core can still be building a SYN-ACK from those options while they are released. The kernel then reads memory it has already given back. Depending on what lands there, the result is kernel data leaking into the reply, a write outside the buffer, or a crash.

Eric Dumazet's fix waits until every reader has finished before the memory is freed. It changes two lines, one in net/ipv4/af_inet.c and one in net/ipv4/tcp_ipv4.c, and the report is credited to Xinyang Ge of Anthropic.

Two details matter for planning. The race happens inside the kernel before any application sees the connection, so every service that accepts IPv4 TCP is in scope. And a failed attempt costs the attacker nothing. Anthropic notes that a lost race only fails one handshake without crashing the server, so the attempts can simply repeat.

Why Multipath TCP Keeps Coming Up

Anthropic's exploit targeted servers with a Multipath TCP listener. MPTCP is a TCP extension that lets one connection use several network paths at once, and current distribution kernels usually ship with it built in.

Few teams ever switched it on deliberately, yet many servers use it. Since Go 1.24, the standard library's ListenConfig opens listening sockets with MPTCP by default on Linux wherever the kernel supports it. A lot of today's infrastructure software is written in Go, so a server can have MPTCP listeners without anyone choosing that. Go takes the default from the Go version a program declares in its go.mod, which means it varies from binary to binary, and the quickest way to know is to look.

Keep the order of things clear. MPTCP is the path that has been demonstrated, not the bug itself. The flaw sits in plain IPv4 TCP, so switching MPTCP off narrows the exposure without closing it. What an MPTCP check does tell you is whether a server matches the published exploit, which is useful for deciding where to start.

Check Your Servers

Start with the kernel version.

uname -r

Compare it with the table above. On Debian, the fixed packages are enough once the machine has rebooted into them. On Ubuntu and RHEL, every kernel released so far is affected.

Then see whether MPTCP is on and whether anything listens with it.

sysctl net.mptcp.enabled
ss -Mltn

A value of 1 means the kernel accepts MPTCP. If sysctl says the key does not exist, MPTCP is not built into that kernel at all. The ss -M flag lists only MPTCP sockets, so an empty table means none of your services listens with it.

Last, note which ports are open to the internet. A service reachable only on a private network is a lower priority than one on a public address.

The Stopgap That Closes the Gap

Red Hat's bulletin RHSB-2026-016 gives a short nftables rule. It drops incoming IPv4 TCP packets whose header carries options, and those options are the only way to reach the bug. A normal IPv4 header is five 32-bit words long, so a header length above five means options are present.

Save this as /etc/cve-2026-98432.nft.

table inet cve_2026_98432 {
    chain input {
        type filter hook input priority -310; policy accept;
        ip protocol tcp ip hdrlength > 5 counter drop
    }
}

Check it, load it and look at it.

sudo nft --check --file /etc/cve-2026-98432.nft
sudo nft --file /etc/cve-2026-98432.nft
sudo nft list table inet cve_2026_98432

We ran exactly this in a Debian 13 container. An ordinary SYN passed through untouched. A SYN carrying a Record Route option, sent with hping3 --rroute, was dropped, and the rule's counter showed those two packets and nothing else.

The rule lives in a table of its own and lets everything else through, so it sits alongside ufw, firewalld, Docker and Kubernetes rules without touching them. It works the same on Ubuntu, where iptables already runs on top of nftables. Legitimate TCP traffic with IP options is rare enough that most servers will never notice, but Red Hat advises trying it on one non-production machine first, and that is sound advice.

Keep It Across Reboots

A table loaded by hand is gone after a reboot. Do not persist it by enabling the stock nftables service, because the default /etc/nftables.conf begins with flush ruleset, which would wipe Docker's and Kubernetes' rules along with everything else. A small service of its own is safer.

# /etc/systemd/system/cve-2026-98432.service
[Unit]
Description=Stopgap filter for CVE-2026-98432
After=network-pre.target
Before=network.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStartPre=-/usr/sbin/nft delete table inet cve_2026_98432
ExecStart=/usr/sbin/nft --file /etc/cve-2026-98432.nft

[Install]
WantedBy=multi-user.target

The first line of the service removes any older copy of the table, so running it twice never stacks duplicate rules.

sudo systemctl daemon-reload
sudo systemctl enable --now cve-2026-98432.service

See Who Is Knocking

The rule's counter doubles as a cheap early warning. Ordinary clients almost never send TCP with IP options, so a number that keeps rising on a public server most likely means someone is scanning for this flaw. The nft list table command above shows it at any time.

To see where those packets come from, put a rate-limited log line in front of the drop.

table inet cve_2026_98432 {
    chain input {
        type filter hook input priority -310; policy accept;
        ip protocol tcp ip hdrlength > 5 limit rate 5/minute counter log prefix "cve-2026-98432 "
        ip protocol tcp ip hdrlength > 5 counter drop
    }
}

The entries land in the kernel log, so journalctl -k | grep cve-2026-98432 lists the sending addresses. Keep the limit and the drop on separate lines, as here. Written as a single rule, the limit would cap the drop as well, and packets above the rate would get through. We checked this version in the same container, and both counters moved together.

A server that was hit before the filter went in is more likely to have crashed than to show anything subtle. An unexplained reboot, or skb_under_panic in the kernel log of the boot before it, deserves a closer look.

journalctl -k -b -1 | grep -E "skb_under_panic|Oops|BUG"

A Second Layer, If You Want One

If nothing on a server needs MPTCP, and on most servers nothing does, switching it off removes the path Anthropic demonstrated. Go programs notice that MPTCP is unavailable and fall back to plain TCP by themselves.

echo "net.mptcp.enabled = 0" | sudo tee /etc/sysctl.d/90-disable-mptcp.conf
sudo sysctl --system

To change one Go service rather than the whole host, set GODEBUG=multipathtcp=0 in that service's environment.

Containers, Kubernetes and Load Balancers

Containers share the host's kernel. The fix and the stopgap both belong on the host or node, and rebuilding an image changes nothing for this bug.

On self-managed Kubernetes, the rule goes on every node. A configuration management run or a short Ansible play is usually simpler to apply and to undo than a privileged DaemonSet. On managed platforms the provider publishes new node images with the fixed kernel, and moving node groups onto them is usually up to you, so watch the provider's bulletin.

A proxy that ends the TCP connection, such as an HTTP load balancer or Cloudflare's proxy, opens its own connection to your server, so a client's IP options never reach you through it. Anything with a public address and an open port is still reachable directly, and that includes SSH.

When the Fixed Kernel Arrives

Install it the usual way and reboot, because a new kernel protects nothing until the machine is running it.

sudo apt update && sudo apt full-upgrade

On RHEL and its relatives the equivalent is sudo dnf update kernel. After the reboot, confirm the version with uname -r, then take the stopgap away.

sudo systemctl disable --now cve-2026-98432.service
sudo nft delete table inet cve_2026_98432
sudo rm /etc/systemd/system/cve-2026-98432.service /etc/cve-2026-98432.nft

The MPTCP setting can stay off if nothing missed it.

What This Means for Your Team

This is a serious flaw with a calm way through it. The fix exists, Debian users can patch today, and everyone else has a tested one-line filter until their kernel lands. A sensible order is public-facing servers first, then anything with an MPTCP listener, then the rest, with the filter applied as you go and removed once each machine runs the fixed kernel.

If you would rather hand the rounds over, we manage Linux servers and can check a fleet, apply the filter and roll out the kernel updates when Ubuntu and Red Hat publish them, with a scope and a price agreed before we start. For an earlier kernel flaw that needed the same kind of triage, see our note on GhostLock.

Sources

Or read how we handle it in Servers Management.