psf-linux-kernel-ireq-opt-check(8)

Script: /opt/psf-security-patches/linux-kernel/linux-kernel-ireq-opt-check.sh. Tool page: Linux kernel. Source. With the package installed: man psf-linux-kernel-ireq-opt-check.

Linux kernel IPv4 TCP use-after-free, remote code execution with MPTCP  (v1)
CVE-2026-98432

If this software is helpful, consider a donation to our 501c3 nonprofit:
https://privacysafe.foundation

A race in the Linux kernel's IPv4 TCP handshake. tcp_v4_syn_recv_sock() hands the request
socket's IP options (ireq->ireq_opt) to the child socket without copying them. A retransmitted
SYN for the same request socket, handled on another CPU, can still be building a SYNACK from
those options when the child socket is destroyed, and inet_sock_destruct() and
tcp_v4_reqsk_destructor() free them with a plain kfree() instead of kfree_rcu(): a use after
free in ip_options_build(). The same happens through request socket migration
(net.ipv4.tcp_migrate_req=1 or a BPF_SK_REUSEPORT_SELECT_OR_MIGRATE program). The attacker is
an unauthenticated peer who sends a SYN that carries IPv4 options (Record Route or Timestamp)
to any listening TCP port: no account, no user interaction. The CVE record scores it 9.8; Red
Hat scores it lower (5.9, Moderate, draft). AWS reports that researchers have demonstrated
unauthenticated remote code execution against a host with a Multipath TCP (MPTCP) listener, and
that a crash, a leak of kernel memory or memory corruption are the other outcomes. At the time of
AWS's bulletin of 2 November there was no evidence of exploitation in the wild.

  Affected: every kernel from 4.4 (commit 079096f103fa) up to the fixed releases below, on
            IPv4. IPv6 is not affected by this flaw. Kernels before 4.4 are not affected.
  First fixed stable release of each branch (the mainline fix is in 7.3):
    5.10.272   5.15.223   6.1.190   6.6.159   6.12.113   6.18.56   7.2.10   7.3
  Every release of a branch not in that list (4.4 to 5.9 other than 5.10, 5.11 to 5.14,
  5.16 to 6.0, 6.2 to 6.5, 6.7 to 6.11, 6.13 to 6.17, 6.19 to 7.1, and older ones such as
  4.14, 4.19 and 5.4) has no upstream fix. Vendors that maintain such a branch backport it.

Why this script reads the kernel's origin first. The upstream patch level is in the release
string only on kernels that follow the stable series (vanilla, Arch, Alpine, most custom
builds). Debian puts it in `uname -v`. Ubuntu, RHEL and its derivatives, SUSE and Amazon Linux
backport fixes under release strings that do not say which fixes they carry, so a number from
them cannot be compared with the table. For those the vendor changelog is the evidence: the
script looks in it for the CVE, and points you to the vendor's tracker when it is absent. A
kernel that is a stable release candidate (-rc) is judged as the release before it.

What the exposure lines mean. They report whether MPTCP is on (net.mptcp.enabled) and built
in, loaded or loadable, how many MPTCP and IPv4 TCP listeners exist, whether
net.ipv4.tcp_migrate_req is set, and whether a filter that drops TCP packets with IP options is
in place. That is information for you to weigh, not a verdict: a kernel below its fixed release
is affected whatever these show. Turning MPTCP off reduces the conditions for running code on
the host; it does not fix the flaw, and a crash stays possible. Go programs built with Go 1.24
or later listen with MPTCP by default when the kernel allows it; GODEBUG=multipathtcp=0 turns
that off for one program. The only complete remedy is a patched kernel and a reboot.

Distributions. Debian, Ubuntu, Trisquel and their derivatives come first: the exact update
command, the apt evidence and the vendor tracker. RHEL, Alma, Rocky, Fedora, CloudLinux, Oracle
Linux and Amazon Linux come next, ready to use: the dnf (or yum) advisory check, `needs-restarting`,
the right kernel package on Amazon Linux 2023 (kernel, kernel6.12 or kernel6.18), and nftables rather
than the iptables front end that has no u32 match. SUSE, Arch and Alpine get the command and the
tracker, nothing more. A fixed kernel that is already installed but not running is reported as such.

A container shows the host's kernel, so run this on the host.

Usage:
  ./linux-kernel-ireq-opt-check.sh [check]
  check (default)  Exit 0 = the running kernel has the fix (or a vendor backport), 1 =
                   affected, or a vendor backport could not be confirmed. Read-only.
  hunt             Read the kernel log for the crash side of the flaw: a call trace through
                   ip_options_build, ip_build_and_send_pkt, tcp_v4_send_synack,
                   tcp_v4_reqsk_destructor or inet_sock_destruct, or a skb_under_panic.
                   It reads dmesg, the journal's kernel messages and the rotated logs under
                   /var/log (kern.log, syslog, messages). A hit means the kernel faulted in
                   this code, not that someone attacked it. A clean result is not clearance: a successful exploit need not crash
                   the host, and a rebooted host has lost its ring buffer. Exit 0 = nothing
                   in the logs that were read, 1 = hits, 2 = no log could be read. Read-only.
  mitigate [--mptcp] [--ip-options] [--modules LIST] [--force] [--dry-run]   (root)
                   changes the host. Reductions, not a fix; they only act when check finds
                   the kernel affected (--force overrides). Choose what to apply:
                     --mptcp         net.mptcp.enabled=0, applied now and written to a
                                     sysctl.d file. Stops new MPTCP sockets; a listener that
                                     exists keeps listening until its service restarts, and
                                     this says so. Breaks software that needs MPTCP (some
                                     mobile and multi-path setups).
                     --ip-options    drops inbound IPv4 TCP packets that carry IP options,
                                     with nftables (a table of its own) or, without it,
                                     iptables (u32 match). Nothing legitimate uses IP options
                                     on TCP, but a few diagnostic tools do. The rule is not
                                     saved: a reboot removes it, which is when the patched
                                     kernel should be running. When a filter of this kind
                                     is already there (Red Hat's table in RHSB-2026-016,
                                     say), it adds nothing and rollback leaves that one alone.
                     --modules LIST  prevents loading of the listed modules, from: mptcp
                                     and mptcp_diag. all means mptcp: mptcp_diag is what
                                     ss -M reads, so it is blocked only when named and with
                                     --force. "install NAME /bin/false" lines in
                                     a modprobe.d file. MPTCP is built into most kernels, and
                                     a modprobe rule cannot block what is built in: use
                                     --mptcp there. A module that is loaded now is left alone
                                     unless --force, which still only blocks later loads.
                   --dry-run shows everything and changes nothing. Previous sysctl values are
                   saved so that rollback can put them back.
  rollback [--dry-run]   restore the saved sysctl values and remove the files and the packet
                   filter mitigate wrote.
  version          print the script version.

Env: KERNEL_CHANGELOG   a vendor changelog file to read, plain or .gz
     STATE_DIR (default /var/lib/psf-security-patches/linux-kernel-ireq-opt), SYSCTL_D and
     MODPROBE_D (default /etc/sysctl.d and /etc/modprobe.d) for mitigate and rollback
     KERNEL_RELEASE, KERNEL_VERSION_STRING   override uname -r and uname -v
     KERNEL_MODULES_FILE, KERNEL_PROC_SYS    override /proc/modules and /proc/sys
     KERNEL_PROTOCOLS_FILE   override /proc/net/protocols (the MPTCP socket count)
     KERNEL_BUILTIN_FILE   override /lib/modules/<release>/modules.builtin
     KERNEL_LOG_FILES   kernel log files for hunt, instead of dmesg, journalctl -k and the
                        usual /var/log files
     KERNEL_INSTALLED_RELEASES   the kernel releases installed, instead of /lib/modules/*
     OS_RELEASE_FILE   instead of /etc/os-release
     PSF_LOCK_WAIT    seconds a run that changes the host waits for another one that is already
                      changing it (default 30); the lock is STATE_DIR/.lock

The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.

The PrivacySafe Ecosystem

Shop at Ivy Cyber

Ivy Cyber offers PrivacySafe products and services in the USA and has partnerships with 3NSoft in Canada and Kuip Limited in the European Union. Enterprise services and consulting are available at ivycyber.com

PrivacySafe Foundation is a 501(c)(3) nonprofit public charity that supports the development of the PrivacySafe applications, along with the components they rely upon: 3NWeb protocols, filesystem, documentation, and reference implementations.

PrivacySafe Foundation

Donations to PrivacySafe Foundation support education, research, documentation, and public code. Purchases from Ivy Cyber support PrivacySafe products, services, hosting, and technical support. Together, we're building a better web.