
Drop incoming IPv4 TCP packets whose IP header contains options.
Drop incoming IPv4 TCP packets whose IP header contains options.
A small, reversible iptables stopgap for CVE-2026-98432.
Drops IPv4 TCP packets containing IP options in the current network namespace. Includes clear status output, repeatable apply/remove commands, a read-only inventory, an optional systemd service and a separate connection check.
Version: 1.0.0 · Review date: 30 October 2026 · Requires: Linux + Bash + iptables
This is community filtering, not a kernel fix or a vendor-certified complete workaround. A present rule does not prove exploit resistance. Install a vendor-fixed kernel and boot into it, or use a supported livepatch that explicitly covers this CVE.
Extract the ZIP, open a terminal in this directory, then:
# Read-only inventory; no root required, although visibility may be limited.
bash paranoid-cve98432.sh audit
# Preview the firewall commands; no changes, no root required.
bash paranoid-cve98432.sh apply --dry-run
# Apply the two runtime rules.
sudo bash paranoid-cve98432.sh apply
# Check exact rules and packet counters.
sudo bash paranoid-cve98432.sh status
Keep your SSH session open and confirm a second SSH connection and your normal services still work. Clients that require IPv4 IP options can be affected.
Undo:
sudo bash paranoid-cve98432.sh remove
Only this tool's exact tagged rules are removed. Other firewall rules and all sysctl settings are preserved. Rules you installed earlier by hand, including the untagged rule from our conversation, are not removed or adopted.
| Dependency | Purpose |
|---|---|
| Bash | Script runtime |
iptables with the IPv4 raw table, u32 and comment matches | Packet filtering |
Root and CAP_NET_ADMIN | Apply, status and remove |
flock, stat, mkdir | Serialize changes using a private directory under /run |
iproute2 (ss) | Optional listener inventory |
| Python 3.8+ | Optional verification helper |
| Python 3.9+ | Offline test suite |
| systemd | Optional boot persistence only |
Typical packages on Ubuntu/Debian:
sudo apt install iptables util-linux iproute2 python3
On RHEL-family systems the package providing the iptables command varies by
release. Check dnf provides '*/iptables'. This tool does not install packages
or change the selected iptables backend.
Some iptables-nft installations do not support u32 in their current setup.
If insertion fails, the tool reports an error and rolls back its new rules.
Do not blindly switch firewall backends on a running server; use a native nftables
equivalent integrated with your existing firewall instead.
These exact rules, with a comment used to identify them:
iptables -w 10 -t raw -I PREROUTING 1 -p tcp \
-m u32 --u32 '0>>24&0x0F=6:15' \
-m comment --comment 'cve98432-guard:v1' -j DROP
iptables -w 10 -t raw -I OUTPUT 1 -p tcp \
-m u32 --u32 '0>>24&0x0F=6:15' \
-m comment --comment 'cve98432-guard:v1' -j DROP
The first byte of an IPv4 header contains the version and Internet Header
Length (IHL). Five 32-bit words is a normal 20-byte header. IHL 6–15 means
there are IP options. u32 reads that field directly.
PREROUTING filters arriving IPv4 TCP traffic before delivery to listeners.OUTPUT also filters locally generated traffic, including attempts to reach
local listeners. It may also drop outgoing replies carrying IP options.These are IPv4 IP options, a different header field from TCP options. Normal SSH, HTTPS and other traffic without IP options is outside the match.
Applying twice does not add more copies. If the second insertion fails, only
rules attempted by that invocation are rolled back; pre-existing exact rules
are retained. remove also cleans up duplicates of this tool's exact rules.
Concurrent invocations of this tool are serialized. An unrelated firewall
manager can still change the rules at the same time.
The upstream advisory describes a use-after-free of IPv4 request/socket options while a SYN-ACK is being built or a request is migrated. The fix changes two destructors to defer freeing through RCU.
Filtering incoming packets with IP options prevents the usual packet-supplied options from reaching TCP on paths covered by these hooks. That is the basis for this stopgap. It is an analysis-based mitigation, not a reproduction of a complete exploit or a guarantee against every route into the vulnerable code.
Check these limits:
| Situation | Limit / action |
|---|---|
| Containers, network namespaces, VPN namespaces | Rules are per namespace. Host rules do not cover traffic confined to another namespace. Inspect and apply inside each relevant namespace. Containers share the host kernel. |
| Linux bridges / layer-2 forwarding | These IPv4 rules are not a complete bridge policy. Ensure destination namespaces are covered; use bridge-family rules if that forwarding path needs filtering. |
| Tunnels | Confirm filtering on the decoded inner IPv4 path. An encrypted outer packet does not expose inner IP options to the outer filter. |
| NetLabel / CIPSO with SELinux or Smack | CIPSO can populate request options through a kernel labeling path. Do not treat ingress-header filtering as coverage for that path. SELinux being enabled alone does not prove CIPSO is configured. |
| Existing sockets or pending requests | Adding a filter is not a cleanup or patch of already-created kernel objects. |
| Firewall reloads | A reload, restore, container orchestrator or administrator may remove/reorder rules. Recheck status and reapply. |
| Earlier raw-table terminating rules | New rules go at position 1, but later rule changes can place a terminating rule ahead of them. Inspect order. |
| A client that requires IP options | Its connections can stop working. This includes specialized security-labeling deployments. |
| IPv6 | These rules do not filter IPv6 or address separately tracked IPv6/CALIPSO migration issues. |
There is no automatic claim that the kernel is patched based on a version string, a changelog mention, empty listener output or a zero packet counter. Vendor kernels backport fixes and have separate generic, cloud, HWE and other flavours. An installed new kernel is not necessarily the running kernel.
Anthropic's 27 October report describes a remote-root exploit against a server with an MPTCP listener. The underlying advisory describes an IPv4 TCP race that is not limited to MPTCP. Both facts matter.
If your applications do not need MPTCP, you can separately disable new MPTCP sockets:
# Record the current value before changing it.
sysctl net.mptcp.enabled
sudo sysctl -w net.mptcp.enabled=0
This setting is per network namespace and controls creation of new sockets. Existing MPTCP listeners are not converted to plain TCP by this command. Identify dependent services and restart/reconfigure them deliberately if needed; this tool does not restart services. Some applications may fail rather than fall back to ordinary TCP.
To persist the change, if you choose to do so, add the line
net.mptcp.enabled = 0 through your normal sysctl configuration. Record the file
and previous runtime value for later restoration. The guard's remove command
does not revert separately made sysctl changes.
net.ipv4.tcp_migrate_req=0 similarly limits one migration mechanism only. A
reuseport BPF migration program is another mechanism, and the primary race
remains. Neither sysctl is a substitute for patching.