
KASAN-verified proof-of-concept reproducing CVE-2026-98432, a Linux kernel IPv4 TCP inet_opt/ireq_opt use-after-free, with cross-CPU race harness and fixed-kernel control.
Linux kernel IPv4 TCP inet_opt/ireq_opt use-after-free (CVSS 9.8).
A SYN with IPv4 header options gets its options saved on the request socket.
When the handshake completes, tcp_v4_syn_recv_sock() hands the same buffer
to the child socket by pointer, no copy. A retransmitted SYN on another CPU
reads it in tcp_v4_send_synack()/inet_csk_route_req() while the child is
already gone (inet_sock_destruct() freed it with plain kfree(), child
sockets have no SOCK_RCU_FREE). Fix is two kfree_rcu() calls, landed in
6.6.159 and friends. Vulnerable since 4.4.
The lab boots a guest kernel so the patched host kernel is never the target:
make image
make kernel-amp kernel-fixed-amp
make rootfs
make test-det-vuln # KASAN: slab-use-after-free in inet_csk_route_req
make test-det-fixed # same attack, clean
phase-det is the cross-CPU repro: dup-SYN flooder pinned to CPU1 (request
socket creation + its timer), final ACKs on CPU0 (child creation), server
accept+close on CPU3 (child destruction). RPS off, attacker/target netns
over a veth pair, packets go out as raw Ethernet frames so the attacker's
own kernel never RSTs the handshake away. The -amp kernels add a 5ms delay
inside inet_csk_route_req between taking ireq_opt and dereferencing it
(KCSAN-style delay injection, used for reproducibility in these repro
kernels only, clearly marked in the source).
poc/poc.c also has timerace, race, migrate and mptcp variants.
evidence/REPRODUCED-UAF-first-splat.txt — 12 splats in one run, first one:
[ 9.076253] BUG: KASAN: slab-use-after-free in inet_csk_route_req+0x94/0x370
[ 9.076586] Read of size 1 at addr ffff888002ddaa41 by task poc/85
...
tcp_v4_send_synack+0x212/0x240
tcp_rtx_synack+0xd5/0x280
inet_rtx_syn_ack+0x38/0x60
tcp_check_req+0xb8e/0xde0
tcp_v4_rcv+0x1131/0x15e0
...
Allocated by task 79: tcp_v4_route_req+0x116/0x1b0 (options saved on the SYN)
Freed by task 80: inet_sock_destruct+0x2cd/0x380 (child close(), plain kfree)
evidence/VERIFIED-fixed-kernel-clean.log — same attack on the kernel with
the two kfree_rcu() calls applied: zero reports.
If you can't patch yet, drop TCP packets carrying IPv4 options at prerouting
(ip protocol tcp ip hdrlength > 5 drop), and set
net.ipv4.tcp_migrate_req=0 for the migration variant. Real fix is the
kernel update.