Linux Kernel TCP Handshake Race RCE (CVE-2026-98432)
A race in Linux IPv4 TCP handshakes since 4.4 frees socket options in use; kernel team scores 9.8, Ubuntu and RHEL ship no fix yet.
TL;DR
- A race condition in the Linux kernel's IPv4 TCP handshake frees a socket's IP options while another CPU still reads them. The kernel's CVE team rates it CVSS v3.1 9.8, and Anthropic researcher Xinyang Ge reported it; Eric Dumazet fixed it on 2026-10-01.
- Every Linux kernel since 4.4 is affected, for any IPv4 TCP service an attacker can reach. Go services built with Go 1.24 or later listen with Multipath TCP by default, which is the configuration Anthropic's exploit used.
- Anthropic says its AI model wrote an exploit that ran commands as root, with no credentials, on Linux servers with an MPTCP listener. No attacks are reported and the flaw is not in CISA's KEV catalog as of 2026-10-30.
- Install a fixed kernel: 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10 or 7.3, or your distribution's fixed package. Debian, Oracle, Amazon and SUSE partly ship fixes; Ubuntu and RHEL released none as of 2026-10-30. See "How do I fix it?" for the Go-only workaround.
Am I affected?
You are exposed when all of these hold:
- Your host runs a Linux kernel from Linux 4.4 (January 2016) onward that predates the fixed stable versions. Containers do not add their own kernel: a service inside a container uses the host's kernel, so the host's version decides.
- An IPv4 TCP service on that host is reachable by the attacker. Red Hat states that a remote attacker who can reach an exposed TCP service could trigger the race.
- The race needs a retransmitted SYN and IP options on the connection request. The kernel team's scoring says an attacker sends a request carrying IPv4 Record Route or Timestamp options, then resends it, and that both sides of the race are attacker-induced.
Two configuration paths widen exposure. A server with a Multipath TCP listener is the configuration Anthropic exploited, and every Go program built with Go 1.24 or later opens listen sockets with MPTCP by default on Linux. Separately, request-socket migration, enabled by net.ipv4.tcp_migrate_req=1 or a BPF reuseport migration program, exposes the same use-after-free through a second path.
| Distribution or kernel | Affected versions | Fixed version |
|---|---|---|
| Mainline and stable, self-built | All since 4.4 | 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10, 7.3 |
| Debian 13 trixie | linux before 6.12.113-1 | linux 6.12.113-1 (2026-10-16) |
| Debian 12 bookworm | linux before 6.1.190-1; linux-6.12 before 6.12.113-1~deb12u1 | 6.1.190-1 (2026-10-17); 6.12.113-1~deb12u1 (2026-10-22) |
| Oracle Linux 7, 8, 9, 10 (UEK) | Kernels before the 2026-10-16 errata | ELSA-2026-500397, ELSA-2026-500398, ELSA-2026-500399 (2026-10-16) |
| Amazon Linux 2023 (kernel6.18) | Before 6.18.56-125.164 | 6.18.56-125.164.amzn2023 (2026-10-24) |
| Amazon Linux 2023 (kernel6.12) | Before 6.12.113-138.209 | 6.12.113-138.209.amzn2023 (2026-10-29) |
| SUSE Linux Micro 6.2, openSUSE Leap 16.0 | Before kernel-default 6.12.0-160000.40.1 | kernel-default 6.12.0-160000.40.1 or later |
| SLES 15 SP4 to SP6 LTSS, SLES 16.0, SLE Micro 5.3 to 5.5 | Before the fixed kernel-default | kernel-default 5.14.21-150400.24.246.1 (SP4, Micro 5.3/5.4), 5.14.21-150500.55.195.1 (SP5, Micro 5.5), 6.4.0-150600.23.143.1 (SP6), 6.12.0-160000.40.1 (SLES 16.0) |
| SLES 15 SP7 | All current kernels | Fix in progress, none released |
| Ubuntu 22.04, 24.04, 26.04, 26.10 (all kernel packages) | All current kernels | None released, work in progress |
| RHEL 8, 9, 10 and OpenShift 4 | All current kernels | Affected, no fix released |
The table has 11 rows; 8 carry a released fix and the remaining 3 do not. Amazon Linux 2 as a whole, and Amazon Linux 2023's default kernel package, also have no fix yet, and Ubuntu lists its cloud, FIPS and real-time kernels as vulnerable or in progress.
Check what runs on each host:
# Host kernel version
uname -r
# Compare against the fixed versions above; on Ubuntu and RHEL, watch the
# vendor advisory instead, because package versions differ from upstream tags.
# Debian: installed kernel packages and status
dpkg -l 'linux-image*' | grep '^ii'
# RHEL, Oracle Linux, Amazon Linux: installed kernels
rpm -q kernel kernel-uek kernel6.12 kernel6.18 2>/dev/null
# Which Go toolchain built a service (Go 1.24+ enables MPTCP by default)
go version -m /path/to/service | head -1
How do I fix it?
- If you run Ubuntu or RHEL, no fixed kernel exists to install yet as of 2026-10-30. Red Hat states no available mitigation meets its standards for easy deployment, suitability for most installations and stability. Watch Ubuntu's CVE page and Red Hat's CVE page for the package, and treat the Go option below only as a stopgap.
- Install your distribution's fixed package and reboot. On Debian:
apt update && apt install linux-image-amd64, then reboot. On Oracle Linux:dnf update kernel-uek, then reboot. On Amazon Linux 2023:dnf update kernel6.18orkernel6.12, then reboot. - On SUSE Linux Micro 6.2 or openSUSE Leap 16.0:
zypper in kernel-default>=6.12.0-160000.40.1, then reboot. - If you build your own kernel, move to one of the fixed stable versions. The kernel CVE team recommends updating to the latest stable kernel and states the community does not support cherry-picking individual fixes.
The Go security team offers one real workaround for Go 1.24 or later services, with its own words of caution. Set GODEBUG=multipathtcp=0 in the program's environment to disable MPTCP at runtime, or put godebug multipathtcp=0 in the main module's go.mod to disable it at build time. Programs can also call net.ListenConfig.SetMultipathTCP(false) per socket. The team calls disabling MPTCP program by program a fragile mitigation: one remaining MPTCP listener still leaves the system vulnerable, and it assumes every viable exploit depends on MPTCP. The team strongly recommends upgrading to a patched kernel instead.
Note the scope: no vendor mitigation covers the underlying race for non-MPTCP listeners, and Red Hat says the most likely result there is a kernel crash, with memory corruption possible in theory.
What is the root cause?
The kernel frees the IP options attached to a TCP connection request while a second CPU is still reading them, because the free uses kfree() instead of waiting for RCU readers.
The IP layer stores options from an incoming IPv4 connection request, such as Record Route or Timestamp, with the request socket. When the handshake completes, tcp_v4_syn_recv_sock() in net/ipv4/tcp_ipv4.c hands that options pointer to the new child socket instead of copying it. Since commit 079096f103fa ("tcp/dccp: install syn_recv requests into ehash table"), request sockets are processed without holding the listener lock.
The fix author's commit message describes the two colliding CPUs. Another CPU can concurrently process a retransmitted SYN for the same request socket and send a SYNACK from tcp_check_req(). tcp_v4_send_synack() and inet_csk_route_req() read ireq->ireq_opt under rcu_read_lock() only, and ip_build_and_send_pkt() and ip_options_build() then read opt->optlen twice. Nothing prevents the child socket from being freed while that SYNACK is still being built.
// net/ipv4/af_inet.c, inet_sock_destruct(), before the fix
void inet_sock_destruct(struct sock *sk)
{
...
WARN_ON_ONCE(sk->sk_wmem_queued);
WARN_ON_ONCE(sk->sk_forward_alloc);
- kfree(rcu_dereference_protected(inet->inet_opt, 1));
+ kfree_rcu(rcu_dereference_protected(inet->inet_opt, 1), rcu);
inet_sock_destruct() frees the child socket's options with a plain kfree(). TCP child sockets do not have SOCK_RCU_FREE, so the free is immediate. A second CPU still inside rcu_read_lock() then reads the freed options in ip_options_build(): a use-after-free.
// net/ipv4/tcp_ipv4.c, tcp_v4_reqsk_destructor(), before the fix
static void tcp_v4_reqsk_destructor(struct request_sock *req)
{
- kfree(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1));
+ kfree_rcu(rcu_dereference_protected(inet_rsk(req)->ireq_opt, 1), rcu);
}
The second path is request-socket migration, enabled by net.ipv4.tcp_migrate_req=1 or a BPF_SK_REUSEPORT_SELECT_OR_MIGRATE program. reqsk_timer_handler() clones the request socket with inet_reqsk_clone(), so the old socket and its clone share the same ireq_opt. When the clone is freed, tcp_v4_reqsk_destructor() frees the options with kfree() while another CPU holding a reference on the old socket can still be using them.
IPv6 is not affected by the first path, because tcp_v6_syn_recv_sock() duplicates the options. The commit notes that tcp_v6_reqsk_destructor() has the same migration issue for CALIPSO-set options and says that will be addressed in a separate patch.
How is it exploited?
No exploit code is public. Anthropic describes the attack its internal AI model built, in four steps:
- The attacker sends an IPv4 TCP connection request carrying IP options to a reachable service, then resends the request to win the race, as the kernel team's scoring describes.
- The race makes the kernel read a length field the attacker controls and copy extra bytes back to the attacker. Once one such over-read returns a kernel pointer, the attacker has defeated KASLR, the kernel's address randomization.
- The same use-after-free then overflows a buffer and overwrites a callback pointer with the address of a payload the attacker staged in kernel memory through an ordinary protocol feature.
- The kernel invokes the callback. The payload chains calls to existing kernel functions and ends with an attacker-chosen shell command running as root.
A lost race only fails that one connection attempt and does not crash the system, so a determined attacker can retry indefinitely. In Anthropic's proof of concept, leaking a kernel pointer took 48 minutes and reaching the shell command took 5 more minutes.
How does the attack flow?
One sentence: an attacker wins the IPv4 TCP handshake race so the kernel frees the request's IP options while a second CPU still reads them in the SYNACK path, then turns the use-after-free into a KASLR leak and a hijacked callback that runs a root command.
IP options"] --> B["Request socket stores
ireq_opt"] B --> C["Handshake completes:
options move to child
without copy"] C --> D["Resent SYN:
second CPU builds SYNACK
reading same options"] D --> E["Child socket freed:
kfree() frees options
still in use"] E --> F["Use-after-free in
ip_options_build()"] F --> G["Info leak or
memory corruption
or crash"] G --> H["Anthropic demo:
root shell on
MPTCP listeners"]
What can an attacker do?
The kernel team's 9.8 score assumes network access, no privileges and no user interaction, with high impact on confidentiality, integrity and availability (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H). In that scenario the bug could send nearby kernel memory back to the attacker, corrupt kernel memory, or crash the system.
Anthropic demonstrated the strongest outcome: arbitrary commands as root, no credentials and no user interaction, on servers exposing an MPTCP listener. Its post does not name the kernel version or configuration tested, and does not say whether servers without an MPTCP listener can be taken over the same way.
Red Hat rates the flaw Important, 8.1, with the vector CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H, on both its CVE page and its machine-readable advisory file, updated on 2026-10-29. Red Hat says the flaw primarily results in a system crash, a denial of service, or potential memory corruption, and calls the score preliminary. Oracle, SUSE and Amazon also score it 8.1 with the same vector. Every vendor score differs from the kernel team's only on attack complexity, which the vendors rate high and the kernel team rates low.
Why does the fix work?
The fix, commit e3f33b0a1d89d738e2b913dab519226eaf76e15b, replaces kfree() with kfree_rcu() in the two destructors, inet_sock_destruct() and tcp_v4_reqsk_destructor(). kfree_rcu() delays the reclaim until an RCU grace period passes, so every CPU that holds rcu_read_lock() around the options finishes reading them before the memory is freed. Readers already used RCU, and the other paths that replace inet_opt, such as do_ip_setsockopt(), already used kfree_rcu().
The two-line change is complete for both IPv4 paths named in the commit: the SYNACK race through inet_sock_destruct() and the migration race through tcp_v4_reqsk_destructor(). The commit itself flags one adjacent item it does not touch: the equivalent IPv6 destructor issue for CALIPSO-set options, which it says a separate patch will address.
How do I check if I was compromised?
No exploitation has been reported anywhere as of 2026-10-30, and no indicators or detection rules have been published. An exploitation attempt that loses the race only fails that connection attempt, so probing can leave little trace.
The mechanism implies what heavy probing would look like: many short-lived IPv4 connection attempts carrying Record Route or Timestamp options, followed by retransmitted requests to the same listening port. Treat that pattern as a lead to investigate, not as proof of compromise; no published source documents observed traffic of this shape.
Timeline
- 2016-01-10: Linux 4.4 ships. The Hacker News reports the flaw was introduced in this release, with the request-socket change that later removed the listener lock from the racing path.
- 2026-10-01: Eric Dumazet authors the fix, "ipv4: free inet_opt and ireq_opt after an RCU grace period", reported by Xinyang Ge of Anthropic.
- 2026-10-05: Kernel developers apply the fix upstream, ten days before the CVE is published.
- 2026-10-11 to 2026-10-15: The fix is backported to the 5.10, 5.15, 6.1, 6.6, 6.12, 6.18 and 7.2 stable branches.
- 2026-10-15: The kernel CVE team publishes CVE-2026-98432.
- 2026-10-16: Debian trixie and Oracle Linux ship fixed kernels (DSA-6568-1; ELSA-2026-500397 to 500399).
- 2026-10-17 to 2026-10-22: Debian 12 bookworm receives fixed kernels in two advisories (DLA-4841-1, DLA-4850-1).
- 2026-10-24: The kernel CVE team adds the 9.8 score to the record, nine days after publishing the CVE. Amazon fixes its kernel6.18 package (ALAS2023-2026-3251).
- 2026-10-27: Anthropic publishes its post describing the AI-written exploit that reached root on MPTCP-listener servers.
- 2026-10-29: Amazon fixes its kernel6.12 package (ALAS2023-2026-3335). Red Hat's CVE page and advisory file move to Important, 8.1. SUSE releases fixed kernels for SLES 15 SP4 to SP6 LTSS and SLE Micro 5.3 to 5.5. The Hacker News publishes the distribution status table.
- 2026-10-30: Ubuntu and RHEL still list no fixed kernel. Neither gives a release date.
FAQ
Does my Go service need the kernel fix even if it never calls MPTCP APIs?
Yes. Go 1.24 and later enable MPTCP by default for listen sockets on Linux, so a plain net.Listen already uses it without any MPTCP call in your code. Check the build with go version -m, and see "How do I fix it?" for the GODEBUG stopgap.
Are containers affected?
The flaw is in the host kernel, so a container does not escape exposure by packaging. Any IPv4 TCP service reachable from the attacker on an affected host, inside or outside a container, gives the attacker the network position the race needs. The fix is the host's kernel package.
Can attackers target IPv6 listeners too?
Not through the first path. The kernel copies the options for IPv6 connections, so the handshake race is IPv4-only. The fix commit notes an IPv6 request-migration issue for CALIPSO-set options that a separate patch will address.
Why does the kernel team say 9.8 while Red Hat and other vendors say 8.1?
The kernel team rates attack complexity low because the attacker induces both sides of the race: the initial request with IP options and the retransmission. Red Hat, Oracle, SUSE and Amazon rate the complexity high, which lowers the score to 8.1 with the same high confidentiality, integrity and availability impact.
Is the flaw being exploited in the wild?
No source reports attacks as of 2026-10-30. The flaw is not in CISA's KEV catalog, checked against the catalog's JSON feed on that date. Anthropic's exploit and its test remain the only demonstrated execution.
I cannot reboot this month. What is my best move?
Install the fixed kernel the moment your distribution ships it, and until then apply the Go team's MPTCP stopgap to Go 1.24 or later services, knowing its limits. Red Hat publishes no accepted mitigation, so keep exposed IPv4 services behind strict network access lists and monitor the Ubuntu and Red Hat advisories daily.
Find the Linux hosts you need to patch first with Ostorlab
Ostorlab's attack surface discovery inventories your internet-facing hosts and the services they expose, so you can list the Linux servers that carry reachable IPv4 TCP listeners and check their kernels first.
References
- CVE-2026-98432 record, kernel.org CNA, published 2026-10-15, updated 2026-10-30, CVSS v3.1 9.8 and the stable backport commits: https://cveawg.mitre.org/api/cve/CVE-2026-98432 (checked October 30, 2026)
- Fix commit e3f33b0a1d89d738e2b913dab519226eaf76e15b, "ipv4: free inet_opt and ireq_opt after an RCU grace period", Eric Dumazet, 2026-10-01: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=e3f33b0a1d89d738e2b913dab519226eaf76e15b (checked October 30, 2026)
- Anthropic, "Discovering and exploiting vulnerabilities in critical, real-world software with Claude", October 27, 2026, chapter 5: https://www.anthropic.com/research/discovering-vulnerabilities-with-claude (checked October 30, 2026)
- The Hacker News, "Linux Kernel TCP Flaw With 9.8 CVSS Score Affects Ubuntu, Red Hat and Other Distributions", October 29, 2026, the distribution status table and the scoring rationale: https://thehackernews.com/2026/10/linux-kernel-tcp-flaw-with-98-cvss.html (checked October 30, 2026)
- Go security team, "[security] Protecting against CVE-2026-98432", golang-announce, October 29, 2026: https://groups.google.com/d/msgid/golang-announce/0c2926bc-e90f-4cdb-97c3-300fff6d8885n%40googlegroups.com (checked October 30, 2026)
- The same Go guidance forwarded to oss-security, October 29, 2026: https://www.openwall.com/lists/oss-security/2026/10/30/1 (checked October 30, 2026)
- Ubuntu CVE-2026-98432 page, no kernel package listed as fixed as of October 30, 2026: https://ubuntu.com/security/CVE-2026-98432 (checked October 30, 2026)
- Red Hat machine-readable advisory for CVE-2026-98432, Important 8.1, updated 2026-10-29: https://security.access.redhat.com/data/csaf/v2/vex/2026/cve-2026-98432.json (checked October 30, 2026)
- Red Hat CVE page for CVE-2026-98432: https://access.redhat.com/security/cve/cve-2026-98432 (checked October 30, 2026)
- Debian DSA-6568-1, linux 6.12.113-1, October 16, 2026: https://lists.debian.org/debian-security-announce/2026/msg00482.html (checked October 30, 2026)
- Oracle Linux CVE-2026-98432 errata page, ELSA-2026-500397 to 500399, released 2026-10-16: https://linux.oracle.com/cve/CVE-2026-98432.html (checked October 30, 2026)
- Amazon Linux 2023 advisory ALAS2023-2026-3251, kernel6.18-6.18.56-125.164, released 2026-10-24: https://alas.aws.amazon.com/AL2023/ALAS2023-2026-3251.html (checked October 30, 2026)
- Amazon Linux 2023 advisory ALAS2023-2026-3335, kernel6.12-6.12.113-138.209, released 2026-10-29: https://alas.aws.amazon.com/AL2023/ALAS2023-2026-3335.html (checked October 30, 2026)
- SUSE CVE-2026-98432 page, Important 8.1, per-package fix status: https://www.suse.com/security/cve/CVE-2026-98432.html (checked October 30, 2026)
- NVD entry for CVE-2026-98432, showing the kernel team's 9.8 score: https://nvd.nist.gov/vuln/detail/CVE-2026-98432 (checked October 30, 2026)
- Kernel CVE team's published record for CVE-2026-98432, recommending the latest stable kernel: https://kernel.googlesource.com/pub/scm/linux/security/vulns/+/refs/heads/master/cve/published/2026/CVE-2026-98432.mbox (checked October 30, 2026)
- Kernel documentation on Multipath TCP: https://docs.kernel.org/networking/mptcp.html (checked October 30, 2026)
- Go issue tracking the discussion, go.dev/issue/82717: https://go.dev/issue/82717 (checked October 30, 2026)
- CISA Known Exploited Vulnerabilities catalog JSON feed, checked for CVE-2026-98432 on October 30, 2026 (not listed): https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json (checked October 30, 2026)