← Back to Feed CACHED · 2026-10-29 09:05:24 · CACHE_KEY CVE-2026-98432
CVE-2026-98432 · CWE-416 · Disclosed 2026-10-15

Linux kernel IPv4 TCP SYN handling use-after-free via RCU-unsafe inet_opt freeing

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Someone left the keys in the ignition of a car parked in a locked garage — technically stealable, but the garage door is on a timer

CVE-2026-98432 is a use-after-free in the Linux kernel's IPv4 TCP stack, present in every kernel from 4.4 through the fix commits (5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10, 7.3-rc7). When tcp_v4_syn_recv_sock() hands off ireq->ireq_opt to a child socket, a second CPU processing a retransmitted SYN for the same request socket can still be reading those options under rcu_read_lock(). Since commit 079096f103fa removed the listener lock from request socket processing, nothing prevents the child socket from being freed mid-SYNACK construction. The result: ip_options_build() reads freed memory. A secondary path exists with request socket migration (net.ipv4.tcp_migrate_req=1), where the old request and its clone share the same ireq_opt. IPv6 is unaffected by the primary path.

The vendor (kernel.org CNA) assigned CVSS 9.8 CRITICAL with AC:L — this is wrong. This is a multi-CPU race condition requiring precise timing between SYN retransmit processing and child socket teardown. Red Hat correctly scored it 5.9 Moderate with AC:H and limited impact to availability only (C:N/I:N/A:H). Red Hat's attack-complexity call is accurate; their impact scope is conservative. An Anthropic research post claims an unreleased AI model chained this bug into a zero-click root RCE in ~53 minutes against an MPTCP listener, using the race for both a KASLR info leak and a callback-pointer overwrite. That chain is unverified and the PoC is withheld, but kernel UAFs in the networking stack have historically been weaponized (cf. CVE-2023-0461, CVE-2024-1086). The real score sits between 5.9 and 9.8 — the race is hard but the kernel is the ultimate high-value target.

"Kernel TCP UAF is remote and real, but the race condition makes 9.8 a fantasy score."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Identify target with exposed TCP listener

The attacker identifies a Linux host running a vulnerable kernel (4.4 through pre-fix) that accepts TCP connections. Any TCP service qualifies — SSH, HTTP, database port, container ingress. The attacker needs only network reachability to the port; no authentication or user interaction is required.
Conditions required:
  • Network path to a TCP listener on a vulnerable Linux host
  • Target kernel version in the affected range (4.4 to pre-fix)
Where this breaks in practice:
  • Many high-value internal services are behind firewalls / segmented VLANs
  • External-facing Linux services often run behind load balancers that terminate TCP, insulating the backend kernel
Detection/coverage: Standard vulnerability scanners (Qualys, Tenable, Rapid7) will flag unpatched kernel versions. uname -r on target is sufficient for version check.
STEP 02

Flood target with crafted SYN retransmissions

The attacker sends SYN packets with IP options set, then retransmits the same SYN to force the kernel to process the retransmission on a different CPU while the first CPU is still handling the original. The goal is to have tcp_check_req() run concurrently with tcp_v4_syn_recv_sock() for the same request socket. This requires high packet rates and timing precision.
Conditions required:
  • Ability to send raw TCP packets with IP options to the target
  • Multi-core target system (single-core systems serialize the processing)
Where this breaks in practice:
  • Winning the race is non-trivial — Red Hat scored AC:H for this reason
  • Network jitter, load balancers, and SYN cookies alter timing windows
  • IDS/IPS signatures for SYN flood patterns may trigger before the race is won
Detection/coverage: Network-level SYN flood detection (Suricata, Snort, cloud DDoS mitigation) will see anomalous SYN rates. GreyNoise and Shodan show no exploitation activity as of 2026-10-29.
STEP 03

Win the race: trigger use-after-free in ip_options_build()

When the race is won, the child socket is freed (via inet_sock_destruct() → kfree(inet_opt)) while the retransmit path is still inside ip_options_build(), which reads opt->optlen from the now-freed memory. On a failed race attempt, the SYN handshake simply fails — no crash occurs — so the attacker can retry indefinitely. Anthropic's claimed PoC required ~48 minutes of sustained retries to achieve the first successful race.
Conditions required:
  • Successful race condition between child socket teardown and SYNACK construction
  • Multi-core system where the two code paths execute on different CPUs
Where this breaks in practice:
  • Each failed attempt is a failed TCP handshake, not a crash — but 48 minutes of anomalous SYN traffic is highly detectable
  • KASLR must be defeated separately before the UAF can be leveraged for code execution
  • Heap layout must be favorable for the freed slab to contain useful data
Detection/coverage: Kernel KASAN (if enabled) will immediately detect the UAF. Production kernels rarely run KASAN, but dmesg may show slab corruption warnings.
STEP 04

Leverage UAF for information leak (KASLR bypass)

Per Anthropic's unverified claim, the attacker manipulates the freed inet_opt slab so that the kernel reads an attacker-controlled length field and sends excess bytes in the SYNACK, potentially including a kernel pointer. This defeats KASLR. The technique is plausible: kernel info leaks via UAF in network-facing code have been demonstrated before (e.g., CVE-2024-1086's nf_tables chain).
Conditions required:
  • Reliable race-win primitive from step 3
  • Heap spray capability to place controlled data in the freed slab
  • Ability to observe the SYNACK response bytes
Where this breaks in practice:
  • Heap grooming in kernel networking slabs is fragile across kernel versions and SLAB/SLUB configurations
  • The Anthropic chain targets MPTCP listeners specifically, which are not enabled by default on most distributions
STEP 05

Achieve kernel code execution

With KASLR defeated, the attacker triggers the race again to overwrite a function pointer in the freed slab, redirecting execution to a ROP/JOP chain built from known kernel gadgets. Anthropic claims this step took ~5 minutes after the KASLR leak. The result is arbitrary kernel code execution — a root shell from network packets.
Conditions required:
  • Successful KASLR bypass from step 4
  • Knowledge of kernel version for gadget selection
  • Heap spray to place payload in the freed slab
Where this breaks in practice:
  • CFI (Control-Flow Integrity) in newer kernels (6.1+ with CONFIG_CFI_CLANG) blocks function-pointer overwrites
  • SMEP/SMAP prevent trivial user-space payload execution
  • The full chain has never been publicly demonstrated or independently verified
Detection/coverage: EDR agents monitoring for anomalous kernel thread behavior or unexpected process spawning from kernel context. Falco rules for unexpected shells.
03 · Compensating Control

1
HIGH 8.1→IGNORE 0.0
SEVERITY REDUCED
Patch to a fixed kernel version immediately on internet-facing hosts — The definitive fix is upstream commit e3f33b0a1d89 (kfree_rcu in inet_sock_destruct and tcp_v4_reqsk_destructor). Deploy within 30 days per noisgate mitigation SLA for HIGH. Prioritize: (1) internet-facing TCP services, (2) Kubernetes nodes, (3) hypervisors, (4) internal infrastructure. Debian and Oracle have packages available now. RHEL users must wait or apply kpatch. Amazon Linux 2023 is fixed in the 6.18 kernel packages.
2
HIGH 8.1→IGNORE 0.0
SEVERITY REDUCED
Apply kernel livepatch (kpatch/livepatch) for zero-downtime mitigation on RHEL/SUSE — Red Hat kpatch and SUSE kernel livepatch can apply the one-liner kfree→kfree_rcu change without rebooting. This is the right path for production hosts that cannot take a maintenance window within 30 days. Check kpatch list for availability of a module targeting this CVE.
3
HIGH 8.1→MEDIUM 5.3
SEVERITY REDUCED
Segment high-value hosts behind network controls that terminate TCP — Place load balancers, reverse proxies, or cloud-native TCP termination (AWS NLB, GCP TCP proxy) in front of vulnerable hosts. The race requires direct TCP handshake participation by the vulnerable kernel — if a proxy terminates the connection, the backend kernel never sees the retransmitted SYN. Deploy within 30 days for hosts that cannot be patched.
4
HIGH 8.1→MEDIUM 6.5
SEVERITY REDUCED
Enable SYN cookie enforcement and rate-limit SYN packets per source — While SYN cookies alone don't prevent the race (it occurs after cookie validation), aggressive per-source SYN rate limiting (iptables -A INPUT -p tcp --syn -m limit --limit 10/s --limit-burst 20 -j ACCEPT) dramatically increases the time needed to win the race. This raises the bar from 48 minutes to potentially hours, making detection near-certain.
5
HIGH 8.1→HIGH 7.5
Monitor for anomalous SYN flood patterns targeting specific ports — The exploit requires sustained SYN retransmission — ~48 minutes per Anthropic's claim. Configure IDS rules (Suricata threshold: type both, track by_src, count 1000, seconds 60) to alert on abnormal SYN rates to specific ports. This won't prevent exploitation but provides early warning with very high confidence.
What doesn't work
  • SELinux / AppArmor — the UAF occurs in kernel space (ip_options_build()), entirely below the MAC enforcement layer. Mandatory access controls cannot prevent kernel memory corruption.
  • Application-layer WAFs (ModSecurity, AWS WAF) — this is a Layer 4 (TCP) attack, not Layer 7. WAFs never see the SYN packets.
  • TCP SYN cookies alone — the race occurs *after* the SYN cookie is validated, during child socket creation. SYN cookies reduce the queue exhaustion risk but do not prevent the concurrent access pattern.
  • Container isolation (namespaces/cgroups) — the vulnerable code runs in the host kernel. A container receiving TCP traffic on a vulnerable host kernel is fully exposed.
04 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone observed. Not in CISA KEV. No GreyNoise, Shadowserver, or Shodan scanner activity detected as of 2026-10-29. Anthropic claims an internal research model built a working chain, but the PoC is withheld under a 45-day embargo.
Proof-of-concept availabilityNo public PoC. No repositories on GitHub named after CVE-2026-98432. Nothing on pocindex.io, ExploitDB, or Nuclei templates. Anthropic's claimed exploit is not published. The only public artifact is the upstream patch commit e3f33b0a1d89.
EPSS score0.00388 (0.39%) — 5th percentile per Rapid7. This places it in the lowest exploitation-probability tier, consistent with the absence of public weaponization.
KEV statusNot listed. No CISA KEV entry as of 2026-10-29.
CVSS vector disputeCNA (kernel.org): CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H = 9.8 CRITICAL. Red Hat: CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H = 5.9 MODERATE. The AC:L vs AC:H disagreement is the crux — this is a race condition, and AC:L is unjustifiable for a multi-CPU race.
Affected versionsLinux kernel 4.4 through pre-fix (introduced by commit 079096f103fa). Every maintained branch was affected.
Fixed versions5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10, 7.3-rc7. Debian: bookworm-security 6.1.190-1, trixie-security 6.12.113-1. RHEL: no fix released yet (bug 2553390 still NEW). Oracle UEK: patched. Amazon Linux 2023: patched in 6.18 packages.
Distro patch statusDebian DSA-6568-1 and DLA-4841-1 issued. SUSE tracking at suse.com/security/cve/CVE-2026-98432. Red Hat has no fix as of 2026-10-29 — RHEL 8, 9, and 10 remain vulnerable.
Disclosure timelineUpstream fix merged: ~2026-10-11 (stable releases 6.18.56, 7.2.10). CVE published: 2026-10-15. Red Hat bug filed: 2026-10-16.
Researcher / orgPatch authored by Eric Dumazet (Google, longtime kernel networking maintainer). The Anthropic exploit chain was attributed to an unnamed internal research model.

Sources.

  1. Debian Security Tracker
  2. Red Hat CVE Page
  3. Red Hat Bugzilla #2553390
  4. Rapid7 Vulnerability Database
  5. stack.watch — Linux kernel TCP UAF
  6. Kernel Changelog 6.18.56
  7. Anthropic Exploit Chain Analysis (explainx.ai)
  8. SUSE CVE Tracker
05 · The Call

Final Verdict
↓ DOWNGRADED to HIGH (8.1/10)

Why this verdict

  • AC:H, not AC:L — the race is real friction. This is a multi-CPU race between tcp_v4_syn_recv_sock() and tcp_check_req(). A failed race simply drops the handshake — no crash. Red Hat correctly scored AC:H. The CNA's AC:L is indefensible for a concurrency bug that Anthropic's own PoC needed 48 minutes to win. This single correction drops the CVSS from 9.8 to 8.1.
  • No public PoC, no in-the-wild exploitation, EPSS in the basement. At 0.39% EPSS, no KEV listing, and no GreyNoise activity, the real-world threat signal is weak. Anthropic's claimed chain is unverified, withheld, and targets MPTCP listeners specifically — a configuration that is not default on any major distribution.
  • Kernel UAFs are historically weaponizable — the floor is HIGH. Despite the friction, kernel use-after-free bugs in the networking stack have been repeatedly turned into RCE by skilled attackers (CVE-2023-0461, CVE-2024-1086, CVE-2024-36971). Dismissing RCE potential would be naive.
  • Role multiplier: the Linux kernel IS the canonical high-value component. This bug lives in the TCP stack — every Linux host running any TCP service is in the blast radius. On a Kubernetes node, exploitation means container escape and node takeover. On a KVM hypervisor, it means guest-to-host escape if the guest can reach a host TCP port. On a network edge appliance (many run Linux), it's a perimeter breach. On a domain-joined host running Samba as a DC, it's domain compromise. ≥10% of Linux kernel installs occupy high-value roles by definition — the floor is HIGH, approaching CRITICAL for canonical infrastructure roles. The race condition friction prevents reaching the CRITICAL floor.

Why not higher?

The race condition is genuine, sustained friction. Anthropic's claimed PoC needed 48 minutes of continuous SYN retransmission — a window easily detected by any network monitoring stack. The MPTCP-specific chain requires a non-default listener configuration. No independent verification of RCE exists. EPSS at 0.39% and zero observed exploitation do not support CRITICAL urgency. The CNA's AC:L scoring is simply wrong for a concurrency bug.

Why not lower?

Kernel UAFs in the networking path are the canonical RCE primitive class in Linux exploitation. Every Linux host accepting TCP connections is affected — this is not a niche subsystem. The UAF is remotely triggerable without authentication, and failed attempts don't crash the target (enabling unlimited retries). Anthropic's unverified claim is plausible given historical precedent. Red Hat's C:N/I:N/A:H is too conservative — it ignores the demonstrated pattern of kernel networking UAFs being escalated to code execution within months of disclosure.

06 · Verification

Crowdsourced verification payload.

Run on each target Linux host as root (or any user with read access to /proc/version). Invoke: sudo bash check_cve_2026_98432.sh. No network access or special tools required — it parses the running kernel version against known-fixed versions. Exit code 1 = VULNERABLE, 0 = PATCHED, 2 = UNKNOWN.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check_cve_2026_98432.sh — Check for CVE-2026-98432
# Linux kernel IPv4 TCP use-after-free in inet_opt handling
# Affected: 4.4 <= kernel < fixed version per branch
# Fixed: 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10, 7.3+

set -euo pipefail

KERNEL=$(uname -r)
# Extract major.minor.patch, stripping distro suffixes
VER=$(echo "$KERNEL" | grep -oP '^[0-9]+\.[0-9]+\.[0-9]+')

if [ -z "$VER" ]; then
  echo "UNKNOWN — could not parse kernel version from: $KERNEL"
  exit 2
fi

MAJOR=$(echo "$VER" | cut -d. -f1)
MINOR=$(echo "$VER" | cut -d. -f2)
PATCH=$(echo "$VER" | cut -d. -f3)

version_ge() {
  # Returns 0 if $MAJOR.$MINOR.$PATCH >= $1.$2.$3
  local cmp_maj=$1 cmp_min=$2 cmp_pat=$3
  if [ "$MAJOR" -gt "$cmp_maj" ]; then return 0; fi
  if [ "$MAJOR" -lt "$cmp_maj" ]; then return 1; fi
  if [ "$MINOR" -gt "$cmp_min" ]; then return 0; fi
  if [ "$MINOR" -lt "$cmp_min" ]; then return 1; fi
  if [ "$PATCH" -ge "$cmp_pat" ]; then return 0; fi
  return 1
}

version_lt() {
  ! version_ge "$1" "$2" "$3"
}

echo "Kernel: $KERNEL (parsed: $MAJOR.$MINOR.$PATCH)"
echo "CVE: CVE-2026-98432 (ipv4 inet_opt UAF)"
echo "---"

# Not affected: kernel < 4.4
if version_lt 4 4 0; then
  echo "PATCHED — kernel predates the vulnerable commit (requires >= 4.4)"
  exit 0
fi

# Check each stable branch
RESULT="UNKNOWN"

if [ "$MAJOR" -eq 5 ] && [ "$MINOR" -eq 10 ]; then
  if version_ge 5 10 272; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif [ "$MAJOR" -eq 5 ] && [ "$MINOR" -eq 15 ]; then
  if version_ge 5 15 223; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 1 ]; then
  if version_ge 6 1 190; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 6 ]; then
  if version_ge 6 6 159; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 12 ]; then
  if version_ge 6 12 113; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -eq 18 ]; then
  if version_ge 6 18 56; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif [ "$MAJOR" -eq 7 ] && [ "$MINOR" -eq 2 ]; then
  if version_ge 7 2 10; then RESULT="PATCHED"; else RESULT="VULNERABLE"; fi
elif version_ge 7 3 0; then
  RESULT="PATCHED"
elif [ "$MAJOR" -eq 4 ] || [ "$MAJOR" -eq 5 ] && [ "$MINOR" -lt 10 ]; then
  # Kernel 4.x (>= 4.4) or 5.x < 5.10 — EOL branches, no backport
  RESULT="VULNERABLE"
elif [ "$MAJOR" -eq 5 ] && [ "$MINOR" -gt 15 ] && [ "$MINOR" -lt 99 ]; then
  # 5.x branches between 5.15 and 6.1 — EOL, no backport
  RESULT="VULNERABLE"
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -gt 1 ] && [ "$MINOR" -lt 6 ]; then
  RESULT="VULNERABLE"
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -gt 6 ] && [ "$MINOR" -lt 12 ]; then
  RESULT="VULNERABLE"
elif [ "$MAJOR" -eq 6 ] && [ "$MINOR" -gt 12 ] && [ "$MINOR" -lt 18 ]; then
  RESULT="VULNERABLE"
else
  # Distro kernel with custom minor — check distro advisories
  RESULT="UNKNOWN"
fi

# Also check for kpatch
KPATCH="not detected"
if command -v kpatch &>/dev/null; then
  if kpatch list 2>/dev/null | grep -qi '98432\|inet_opt'; then
    KPATCH="livepatch applied"
    RESULT="PATCHED"
  fi
fi

echo "kpatch: $KPATCH"
echo "Result: $RESULT"

case $RESULT in
  VULNERABLE) echo "ACTION: Upgrade kernel to a fixed version."; exit 1 ;;
  PATCHED)    echo "No action required for this CVE."; exit 0 ;;
  UNKNOWN)    echo "Could not determine status — check distro advisory."; exit 2 ;;
esac