
Mitigation toolkit for the IPv4 TCP inet_opt/ireq_opt use-after-free: exposure audit, nft SYN-with-IP-options drop rules, tcpdump detection, and kpatch/livepatch builder for EL kernels.
IPv4 TCP inet_opt/ireq_opt use-after-free (upstream fix e3f33b0a,
kfree → kfree_rcu in inet_sock_destruct() + tcp_v4_reqsk_destructor()).
Trigger: client SYN carrying IPv4 options (ihl > 5) — without options the
raced object ireq_opt is never allocated. The claimed remote-root exploit
additionally needs an MPTCP listener.
| file | needs root | purpose |
|---|---|---|
cve-audit.sh | no | read-only exposure + patchability report |
cve-mitigate.sh | apply/undo | nft drop of SYNs with IP options, optional MPTCP off |
nft-rules.txt | — | the ruleset standalone (nft -f nft-rules.txt) |
cve-detect.sh | capture modes | tcpdump sensor for the exploit's packet shape |
kpatch-el-build.sh | build/install | validated kpatch/livepatch builder for EL family |
klp-handcraft-build.sh | build/load | hand-written klp module for IBT kernels where kpatch-build cannot run (EL10) |
patches/CVE-2026-98432.patch | — | upstream fix, ready for kpatch-build |
tests/run-tests.sh | no | harness (netns ruleset load + stubbed builder e2e) |
./cve-audit.sh # where do I stand?
./cve-mitigate.sh apply --with-mptcp-off # closes trigger + claimed root path
./cve-detect.sh count 30 # anyone probing with IP options?
sudo ./kpatch-el-build.sh --name CVE-2026-98432 \
--expect inet_sock_destruct,tcp_v4_reqsk_destructor \
[--sign priv.pem cert.pem] [--install] \
patches/CVE-2026-98432.patch
# verify: cat /sys/kernel/livepatch/CVE-2026-98432/enabled -> 1
./cve-mitigate.sh status # keep until 100% patched, then:
./cve-mitigate.sh undo
| target | notes |
|---|---|
| EL7 (3.10) | not vulnerable (trigger code arrived in 4.4); builder still works for other patches |
| EL7h/EL8 (4.18) | vulnerable; kernel-debuginfo provides /usr/src/debug/kernel-*/linux-*; kpatch-build from EPEL |
| EL9 (5.14) | vulnerable; kernel built with gcc-toolset — builder auto-prepends matching /opt/rh/gcc-toolset-* |
| EL10 (6.12) | IBT: kpatch-build 0.9.11 refuses CONFIG_X86_KERNEL_IBT=y kernels (dynup/kpatch#1320) — use klp-handcraft-build.sh; module signing enforced under Secure Boot/lockdown |
| CloudLinux 8/9/10 | distro id not in kpatch-build's support list, hence builder always passes -s/-c/-v explicitly; debuginfo comes from the AlmaLinux/CentOS kernel-debuginfo matching rpm -qf /boot/vmlinuz-$(uname -r) |
Debuginfo on RHEL needs repos enabled, e.g.
dnf --enablerepo='*debug*' debuginfo-install -y $(rpm -qf /boot/vmlinuz-$(uname -r))
(subscription-manager repos --enable=rhel-9-appstream-rpms etc. on unbilled hosts).
CONFIG_LIVEPATCH=y + CONFIG_KALLSYMS=y in the running config..comment-level check delegated to
kpatch-build; toolset lookup done here).--expect) — a surprise third change object is a hard fail.sign-file with your keypair + modinfo sig_type re-check;
enroll the cert via MOK for Secure Boot.--install drops into /var/lib/kpatch/$(uname -r)/, loads via
kpatch/insmod, enables kpatch.service for reboot persistence.uname -r as fleet../kpatch-el-build.sh ... --install; confirm
/sys/kernel/livepatch/<name>/enabled == 1.hping3 -S -p <port> --tcp-opts ... flood
at a listener while toggling net.ipv4.tcp_migrate_req=1 on the canary;
KASAN kernel variant with an artificial udelay() inside
ip_options_build() should reproduce the UAF without the patch and stay
silent with it.uname -r untouched (livepatch doesn't bump it), kpatch list,
dmesg -w for taint and klp transition stalls
(/sys/kernel/livepatch/<name>/transition must drain to 0).Harness: all checks pass on an AlmaLinux 10.2 VM (kernel 6.12.0-211.64.1.el10_2).
Real nft rulesets are loaded and listed inside a fresh netns; pcap filters
compiled against live tcpdump; builder pipeline exercised end-to-end against
a stubbed kpatch-build with a real .ko fixture and injected symbol feeds.
Verified live on that EL10 VM:
klp-handcraft-build.sh --load built and enabled a livepatch:
/sys/kernel/livepatch/klp_CVE_2026_98432/enabled=1, transition drained,
sysfs lists inet_sock_destruct,1 + tcp_v4_reqsk_destructor,1; normal
TCP (HTTP 200) unaffected. Unsigned .ko taints the kernel; Secure Boot
lockdown would refuse it (VM ran unsigned).kpatch-build (dynup 0.9.11, built from source) hard-fails on EL10
with "kernel option CONFIG_X86_KERNEL_IBT not supported" — the builder
now preflights this and points at the handcraft route. A real binary-diff
kpatch-build run remains unexercised on EL8/EL9.prerouting priority -310 works for the same reason.
Run the happy path once on your EL canary before trusting it in an incident.