TCP2RootShell: Linux kernel IPv4 TCP use-after-free (CVE-2026-98432)
KubeGenie

CVE-2026-98432

TCP2RootShell

A race in the Linux kernel's IPv4 TCP handshake frees memory that is still in use. Any server that accepts IPv4 TCP connections runs the affected code. Patch your kernel and reboot.

SYNACKRSTFIN
opt: RR / TS
9.8CRITICAL
CVSS 3.1, kernel CNA

Summary

A use-after-free in ip_options_build(), reachable during the IPv4 TCP handshake by an unauthenticated remote peer. It affects every kernel from Linux 4.4 until the fixed stable releases. The kernel CNA rates it 9.8 Critical. Anthropic has described a working remote root exploit against servers with a Multipath TCP (MPTCP) listener, but has not published it.

Componentnet/ipv4 (TCP)
IntroducedLinux 4.4 (2016)
AttackRemote, no auth
In the wildNone reported

Status as of 30 October 2026. Not in the CISA Known Exploited Vulnerabilities catalogue at that date.

Who's exposed

The vulnerable code runs inside the kernel while it handles incoming connection requests, before any application sees the connection. If a host listens on an IPv4 TCP port that an attacker can reach, the attacker can reach the bug. No credentials and no user interaction are needed.

IPv6: the main path does not affect IPv6, because tcp_v6_syn_recv_sock() copies the options. A similar issue exists on the IPv6 migration path, limited to CALIPSO options; upstream plans a separate patch for it.

The bug

A client can put IPv4 options, such as Record Route or Timestamp, in its SYN. The kernel stores them with the half-open connection in ireq_opt, because the SYNACK has to echo them back. When the handshake completes, tcp_v4_syn_recv_sock() hands that pointer to the new child socket's inet_opt without copying the data.

If the client retransmits its SYN at the right moment, another CPU builds a fresh SYNACK from the same options. Since commit 079096f103fa (Linux 4.4), request sockets are processed without the listener lock, so nothing stops the child socket from being torn down in the meantime. Its destructor frees the options with a plain kfree(), and the SYNACK path reads freed memory.

CPU A: handshake completes

  1. ACK arrives, tcp_v4_syn_recv_sock() runs
  2. Child socket takes ireq_opt as inet_opt, no copy
  3. Connection is torn down
  4. inet_sock_destruct() calls kfree(inet_opt)

CPU B: retransmitted SYN

  1. Same request socket, tcp_check_req()
  2. tcp_v4_send_synack() reads ireq_opt under RCU only
  3. ip_options_build() reads optlen and offsets
  4. Use-after-free

The kernel CNA's scoring notes describe three outcomes once the freed object is reclaimed:

The fix by Eric Dumazet, upstream commit e3f33b0a1d89, changes two kfree() calls to kfree_rcu(), in inet_sock_destruct() (net/ipv4/af_inet.c) and tcp_v4_reqsk_destructor() (net/ipv4/tcp_ipv4.c). Readers already used RCU; now the memory waits for them.

- kfree(rcu_dereference_protected(inet->inet_opt, 1));
+ kfree_rcu(rcu_dereference_protected(inet->inet_opt, 1), rcu);

A lost race only fails that one handshake. It does not crash the server, so an attacker can keep retrying as long as the port is open.

Exploitation status

Be wary of repositories advertising a "PoC" or "checker" for this CVE. No exploit has been published by the researchers. Do not run untrusted code on production hosts.

MPTCP and Go

On Linux, an application only gets MPTCP if it asks for it when it opens a socket, so for years most teams could assume they were not running it. Go changed that: since Go 1.24, Go programs enable MPTCP on listening sockets by default where the kernel supports it. Gateways, reverse proxies and internal services written in Go may hold MPTCP listeners their owners never asked for.

Whether the kernel allows it depends on net.mptcp.enabled. RHEL 8, 9 and 10 and their rebuilds ship with it set to 0; distributions that keep the upstream default ship 1.

The Go Security Team's guidance (29 October) for disabling the default:

# at runtime, per program
GODEBUG=multipathtcp=0 ./your-service

# at build time, in the main module's go.mod
godebug multipathtcp=0

Code calling SetMultipathTCP on a net.ListenConfig or net.Dialer overrides both. The Go team calls this a fragile mitigation and recommends a patched kernel.

Affected kernels

Every Linux kernel from 4.4 onwards, until these stable releases:

Stable branchAffectedFirst fixed release
5.10below 5.10.2725.10.272
5.15below 5.15.2235.15.223
6.1below 6.1.1906.1.190
6.6below 6.6.1596.6.159
6.12below 6.12.1136.12.113
6.18below 6.18.566.18.56
7.2below 7.2.107.2.10
Mainlinebelow 7.37.3
Older than 4.4not affectedn.a.
Source: CVE record from the Linux kernel CNA. Other end-of-life branches from 4.4 onwards have no fix.
Distribution kernels backport fixes onto their own version numbers. Ubuntu's 6.8.0 or RHEL's 5.14.0 tell you nothing against this table; use your distribution's advisory below.

Distribution status

DistributionStatusFixed kernel or advisory
Debian 13 (trixie)Fixedlinux 6.12.113-1 (DSA-6568-1)
Debian 12 (bookworm)Fixedlinux 6.1.190-1 (DLA-4841-1), linux-6.12 6.12.113-1~deb12u1 (DLA-4850-1)
Oracle Linux 7-10 (UEK)FixedELSA-2026-500397, -500398, -500399 (16 October)
SLES 16.0, openSUSE Leap 16.0, SL Micro 6.2Fixedkernel-default 6.12.0-160000.40.1
SLES 15 SP4-SP6 LTSS, SLE Micro 5.3-5.5FixedSee SUSE's CVE page
SLES 15 SP7In progressNone released
Amazon Linux 2023, kernel6.18FixedALAS2023-2026-3251
Amazon Linux 2023, kernel6.12FixedALAS2023-2026-3335
Amazon Linux 2023 default kernel; Amazon Linux 2PendingNone released
Ubuntu 22.04, 24.04, 26.04, 26.10In progressNone released
Ubuntu 16.04, 18.04, 20.04VulnerableNone announced
RHEL 8, 9, 10 (incl. kernel-rt), OpenShift 4 (RHCOS)AffectedNone released, no date
AlmaLinux, Rocky Linux, Oracle Linux RHCK 8-10AffectedFollow RHEL; AlmaLinux has kernels in testing
RHEL 7, CentOS 7Not affectedn.a.
As of 30 October 2026. Check your vendor's tracker for current status.

Installing a fixed kernel package is not enough. The running kernel stays vulnerable until the host reboots into the new one, or a livepatch for this specific CVE is applied.

Why the scores differ

Your scanner may show this CVE as Critical on one host and Moderate or Important on another.

SourceCVSS 3.1Vector
Linux kernel CNA, Ubuntu9.8 CriticalAV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
SUSE, Amazon, Oracle8.1AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
Red Hatinitially 5.9 Moderate, raised to 8.1 Important around 29 October5.9 scored availability impact only

The remaining disagreement is attack complexity. Vendors rate a cross-CPU race as hard to win; the CNA argues both sides of the race are attacker-induced and a lost race costs nothing but one connection attempt. If your patch SLA keys off vendor severity, treat this CVE as remote code execution regardless.

Check your hosts

# running kernel (compare against your vendor's advisory, not upstream)
uname -r

# is the fix in the running kernel's changelog?
apt changelog linux-image-$(uname -r) 2>/dev/null | grep CVE-2026-98432   # Debian, Ubuntu
rpm -q --changelog kernel-$(uname -r) | grep CVE-2026-98432               # RHEL family, Amazon Linux
rpm -q --changelog kernel-default | grep CVE-2026-98432                   # SUSE

# installed but not yet booted?
[ -f /var/run/reboot-required ] && echo "Reboot required"                 # Debian, Ubuntu
needs-restarting -r                                                       # RHEL family

# MPTCP allowed, migration path closed?
sysctl net.mptcp.enabled net.ipv4.tcp_migrate_req

# every line printed is an MPTCP listener (needs a recent iproute2)
ss -H -lMnp

Check everywhere Linux runs: bare metal, VMs, Kubernetes and OpenShift nodes, appliances, CI runners. Containers share the host kernel, so patching images does nothing here; patch and reboot the nodes.

Fix it

Install your distribution's fixed kernel, then reboot into it (or apply a livepatch that covers this CVE).

# Debian (ensure security.debian.org is in your sources), Ubuntu once released
sudo apt update && sudo apt full-upgrade && sudo reboot

# RHEL family, Amazon Linux, Oracle Linux, once released
sudo dnf upgrade kernel && sudo reboot

# SUSE
sudo zypper patch && sudo reboot

If you build your own kernels, move to the latest release on your stable branch from the table above. The kernel CVE team recommends that over cherry-picking individual fixes.

Prioritise internet-facing hosts with open IPv4 TCP ports, then anything with MPTCP listeners or Go services, then internal hosts.

If you can't patch yet

Red Hat states no mitigation meets its criteria, and no vendor has validated the options below against an exploit. They follow from how the bug works. Test them in staging, and do not treat them as a substitute for a fixed kernel.

1. Turn MPTCP off where nothing needs it

sudo sysctl -w net.mptcp.enabled=0
echo 'net.mptcp.enabled = 0' | sudo tee /etc/sysctl.d/90-cve-2026-98432.conf
# then restart services that already opened MPTCP listeners

Removes the listener the demonstrated chain needs. The bug is still reachable through plain IPv4 TCP.

2. Keep request socket migration off

sysctl net.ipv4.tcp_migrate_req   # should print 0 (the default)

3. Drop inbound TCP packets carrying IPv4 options

The main path needs IP options in the SYN, and normal TCP traffic does not carry them. This rule matches any IPv4 header longer than 20 bytes, so it covers Record Route and Timestamp alike, MPTCP or not:

nft add table ip cve_2026_98432
nft add chain ip cve_2026_98432 prerouting '{ type filter hook prerouting priority -300; }'
nft add rule ip cve_2026_98432 prerouting meta l4proto tcp ip hdrlength != 5 drop

# undo
nft delete table ip cve_2026_98432

Not persistent across reboots; add it to your firewall configuration if you keep it. Filtering IP options at the network edge covers every host behind it, provided all traffic passes through that edge.

4. Watch for crashes

journalctl -k | grep -E 'ip_options_build|ip_build_and_send_pkt|skb_under_panic'

Timeline

  1. Linux 4.4 ships commit 079096f103fa, which introduces the race
  2. Eric Dumazet's two-line fix is applied upstream, reported by Xinyang Ge (Anthropic)
  3. The kernel CVE team publishes CVE-2026-98432
  4. Oracle fixes UEK; Debian fixes trixie (DSA-6568-1)
  5. Debian fixes bookworm (DLA-4841-1, DLA-4850-1)
  6. The kernel CNA adds its 9.8 score; Amazon fixes kernel6.18
  7. Anthropic describes a remote root exploit against an MPTCP listener
  8. Red Hat raises its rating to Important; SUSE ships kernel advisories; Amazon fixes kernel6.12; the Go Security Team publishes guidance
  9. AlmaLinux publishes patched kernels for testing. RHEL and Ubuntu fixes still pending

About the name

Every serious bug now seems to arrive with a something2shell domain. This one starts with a TCP SYN and, in the configuration Anthropic demonstrated, ends in a root shell. Hence TCP2RootShell. The name describes the demonstrated chain; root has not been publicly shown on hosts without an MPTCP listener.

To be clear, we did not find, fix or exploit this bug. Credit belongs to the people who did the work: Xinyang Ge of Anthropic reported it, Eric Dumazet fixed it, and Anthropic's Frontier Red Team did the exploitation research. The Linux kernel CVE team published and scored it, and the distribution security teams are shipping the fixes.

Sources