There is a severe TCP Use-After-Free: CVE-2026-98432 without proper mitigation via stock Linux Kernels from Ubuntu. However Ubuntu has published an advisory. Here is a script that applies temporary mitigation on Ubuntu

This script is based on the advisory : https://web.archive.org/web/20261103091553/https://ubuntu.com/security/CVE-2026-98432

How to run:

bash cve-2026-98432-mitigation.sh apply

The script:

#!/usr/bin/env bash
#
# Mitigation for CVE-2026-98432 (Linux kernel IPv4 TCP ireq_opt use-after-free).
# Drops inbound IPv4 TCP packets that carry IP options, using a private
# nftables table. This REDUCES risk; it is not a fix. Install the patched
# kernel as soon as it is available and reboot.
#
# Usage: sudo ./cve-2026-98432-mitigation.sh {apply|unapply|status}
#
# Env: WITH_FORWARD=1 also drop such packets on the forward hook (protects
# containers/VMs behind this host; breaks IP options
# on transit traffic if this host is a router).
#
# Persistence uses a dedicated systemd unit that loads ONLY our own table,
# so /etc/nftables.conf (and its "flush ruleset") is never touched and other
# firewalls (ufw, firewalld, Docker, libvirt) are not disturbed.
set -euo pipefail
umask 022
CVE="cve-2026-98432"
TABLE="cve_2026_98432"
RULE_FILE="/etc/${CVE}.nft"
UNIT_NAME="${CVE}-mitigation.service"
UNIT_FILE="/etc/systemd/system/${UNIT_NAME}"
NFT_CONF="/etc/nftables.conf"
LEGACY_INCLUDE="include \"${RULE_FILE}\""
WITH_FORWARD="${WITH_FORWARD:-0}"
die() { echo "Error: $*" >&2; exit 1; }
warn() { echo "Warning: $*" >&2; }
[ "${EUID}" -eq 0 ] || die "run as root (use sudo)."
NFT_BIN="$(command -v nft || true)"
[ -n "${NFT_BIN}" ] || die "nftables (nft) is not installed or not in PATH."
TMP_FILES=()
cleanup() { [ "${#TMP_FILES[@]}" -gt 0 ] && rm -f "${TMP_FILES[@]}"; return 0; }
trap cleanup EXIT
# Sets $TMP (no command substitution, so TMP_FILES is updated in this shell).
TMP=""
mktmp() { TMP="$(mktemp)"; TMP_FILES+=("${TMP}"); }
have_systemd() { command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ]; }
# Single-instance lock
exec 9>"/run/${CVE}-mitigation.lock"
flock -n 9 || die "another instance is already running."
render_rules() {
# add+delete makes the file idempotent: re-loading replaces the table
# instead of appending a duplicate rule.
cat <<EOF
add table inet ${TABLE}
delete table inet ${TABLE}
table inet ${TABLE} {
chain input {
type filter hook input priority -310; policy accept;
ip protocol tcp ip hdrlength > 5 counter drop
}
EOF
if [ "${WITH_FORWARD}" = "1" ]; then
cat <<EOF
chain forward {
type filter hook forward priority -310; policy accept;
ip protocol tcp ip hdrlength > 5 counter drop
}
EOF
fi
echo "}"
}
render_unit() {
cat <<EOF
[Unit]
Description=CVE-2026-98432 mitigation (drop IPv4 TCP packets with IP options)
DefaultDependencies=no
After=local-fs.target nftables.service
PartOf=nftables.service
Wants=network-pre.target
Before=network-pre.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=${NFT_BIN} -f ${RULE_FILE}
ExecStop=-${NFT_BIN} delete table inet ${TABLE}
[Install]
WantedBy=multi-user.target
EOF
}
table_loaded() { "${NFT_BIN}" list table inet "${TABLE}" >/dev/null 2>&1; }
apply_mitigation() {
echo "Applying ${CVE} mitigation..."
# 1. Render to a temp file and validate BEFORE touching anything on disk.
local tmp; mktmp; tmp="${TMP}"
render_rules > "${tmp}"
"${NFT_BIN}" -c -f "${tmp}" || die "rule validation failed; nothing changed."
# 2. Install atomically (no clobber of a good file with a bad one).
install -m 0644 -o root -g root "${tmp}" "${RULE_FILE}"
echo "Installed ${RULE_FILE}"
# 3. Load into the live ruleset (idempotent).
"${NFT_BIN}" -f "${RULE_FILE}"
table_loaded || die "table ${TABLE} not present after load."
echo "Live rule loaded."
# 4. Boot persistence via our own unit.
if have_systemd; then
local utmp; mktmp; utmp="${TMP}"
render_unit > "${utmp}"
install -m 0644 -o root -g root "${utmp}" "${UNIT_FILE}"
systemctl daemon-reload
systemctl enable "${UNIT_NAME}" >/dev/null \
|| die "live rule is active, but enabling ${UNIT_NAME} failed (no persistence)."
echo "Persistence enabled (${UNIT_NAME})."
else
warn "systemd not detected: rule is live but will NOT survive a reboot."
fi
if grep -Fxq "${LEGACY_INCLUDE}" "${NFT_CONF}" 2>/dev/null; then
echo "Note: legacy include found in ${NFT_CONF}; harmless (rule file is idempotent)."
fi
warn "this is a partial mitigation. Install the kernel fix when released: uname -r = $(uname -r)"
[ "${WITH_FORWARD}" = "1" ] || \
echo "Note: forwarded traffic (containers/VMs behind this host) is NOT covered; use WITH_FORWARD=1 if needed."
echo "Mitigation applied."
}
unapply_mitigation() {
echo "Removing ${CVE} mitigation..."
if have_systemd && [ -f "${UNIT_FILE}" ]; then
systemctl disable --now "${UNIT_NAME}" >/dev/null 2>&1 || true
rm -f "${UNIT_FILE}"
systemctl daemon-reload
echo "Removed ${UNIT_NAME}."
fi
if table_loaded; then
"${NFT_BIN}" delete table inet "${TABLE}"
echo "Removed live table inet ${TABLE}."
else
echo "Live table not present."
fi
# Clean up a legacy include from the vendor/old-script method, if present.
if [ -f "${NFT_CONF}" ] && grep -Fxq "${LEGACY_INCLUDE}" "${NFT_CONF}"; then
local bak t
bak="${NFT_CONF}.bak.$(date +%Y%m%d%H%M%S)"
mktmp; t="${TMP}"
cp -p "${NFT_CONF}" "${bak}"
grep -Fxv "${LEGACY_INCLUDE}" "${NFT_CONF}" > "${t}" || true
cat "${t}" > "${NFT_CONF}" # preserves mode/owner/symlink
echo "Removed legacy include from ${NFT_CONF} (backup: ${bak})."
fi
rm -f "${RULE_FILE}"
echo "Mitigation removed."
}
status() {
echo "Kernel: $(uname -r)"
if table_loaded; then
"${NFT_BIN}" list table inet "${TABLE}"
else
echo "Table inet ${TABLE}: NOT loaded"
fi
if have_systemd; then
echo "Boot persistence: $(systemctl is-enabled "${UNIT_NAME}" 2>/dev/null || echo not-enabled)"
fi
}
case "${1:-}" in
apply) apply_mitigation ;;
unapply) unapply_mitigation ;;
status) status ;;
*) echo "Usage: $0 {apply|unapply|status}" >&2; exit 1 ;;
esac

Leave a Reply

Your email address will not be published. Required fields are marked *

Your post must include a link to this post.

How does this work?
Write a response on your own website and include a link to this post. Then submit your response’s URL here. Your response may appear here after moderation. To update or remove it, edit or delete your original post and submit the same URL again. Learn more about Webmentions.