
Guida e script di verifica in sola lettura per CVE-2026-98432, una use-after-free nel TCP IPv4 di Linux: rileva lo stato della patch del kernel, applica una soluzione tampone con iptables e verifica dopo la correzione.
Attaccabile tramite la rete, senza login e senza azione dell'utente. Il bug si trova nel codice del kernel che gestisce ogni connessione TCP IPv4 in entrata.
Questa guida mostra come verificare un server, proteggerlo finché non è disponibile un kernel corretto e ripulire in seguito. I comandi seguenti sono stati usati su server Ubuntu 22.04 e 24.04.
Lo stato in questo documento è aggiornato al 2026-10-30. Lo stato delle patch cambia rapidamente, quindi controlla sempre il security tracker della tua distribuzione.
e3f33b0a1d89In parole semplici: una richiesta di connessione (SYN) può trasportare opzioni IPv4, extra usati raramente nell'intestazione del pacchetto come Record Route o Timestamp. Quando ne arriva una, il kernel conserva una copia di quelle opzioni. Se l'attaccante reinvia il SYN nel momento esatto, una CPU può liberare quella copia mentre un'altra la sta ancora usando per costruire la risposta. Si tratta di un use-after-free in ip_options_build(), che può mandare in crash il server o corrompere la memoria del kernel.
Esiste un secondo innesco quando il server migra le richieste di connessione in sospeso tra socket (net.ipv4.tcp_migrate_req=1, oppure un programma BPF_SK_REUSEPORT_SELECT_OR_MIGRATE). Tale impostazione è disattivata per impostazione predefinita.
| Priorità Ubuntu | Alta |
| CVSS, CNA del kernel | 9.8 Critico: rete, nessuna autenticazione, nessuna interazione dell'utente |
| CVSS, Red Hat | 8.1, perché Red Hat ritiene la race più difficile da sfruttare |
| Interessati | Kernel dalla 4.4 in poi |
| IPv6 | Non interessato dal problema principale |
| Sfruttamento | Nessuno segnalato in the wild, e non presente nel catalogo CISA KEV. Un exploit remoto per root contro server con un listener multipath TCP (MPTCP) è stato segnalato ma non pubblicato. |
Chi è esposto: qualsiasi server con una porta TCP raggiungibile su IPv4, che sia SSH, HTTP, HTTPS o altro.
| Distribuzione | Stato | Corretto in |
|---|---|---|
| Kernel upstream | ✅ Corretto | 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10, 7.3 |
| Debian 12 / 13 | ✅ Corretto | 6.1.190-1 (oppure linux-6.12 6.12.113-1~deb12u1) / 6.12.113-1 |
| Ubuntu 26.10 / 26.04 / 24.04 / 22.04 | ❌ Correzione in corso, non rilasciata | Previsto: 7.3.0-10.10 / 7.0.0-43.43 / 6.8.0-149.149 / 5.15.0-203.213 |
| Ubuntu 20.04 / 18.04 / 16.04 | ❌ Vulnerabile | Solo tramite Ubuntu Pro (ESM), se mai |
| RHEL 8 / 9 / 10 | ❌ Segnalato come "correzione rinviata" | Nessuna |
| Oracle Linux (UEK) | ✅ Corretto | ELSA-2026-500397 / 500398 / 500399 |
| Amazon Linux 2023 | ⚠️ Parzialmente corretto | kernel6.18 e kernel6.12 corretti; kernel predefinito e AL2 in sospeso |
| SUSE | ⚠️ Parzialmente corretto | openSUSE Leap 16.0 corretto; SLES in corso |
I kernel cloud di Ubuntu (-aws, -azure, -gcp, -oracle) hanno numeri di versione propri. I kernel delle distribuzioni applicano backport delle correzioni, quindi non confrontare una versione della distro come 5.15.0-xxx con i numeri upstream.
Questo si limita a leggere e riportare. Non installa, modifica o riavvia nulla. Incollalo in un terminale sul server:
sudo bash -s <<'EOF'
CVE=CVE-2026-98432; FIX="free inet_opt and ireq_opt"; KR=$(uname -r)
. /etc/os-release
echo "== $PRETTY_NAME | running kernel: $KR"; echo " build: $(uname -v)"
echo "== Installed kernels (if one is newer than the running kernel, you need a reboot)"
ls -1v /boot/vmlinuz-* 2>/dev/null | sed 's|/boot/vmlinuz-| |'
[ -f /var/run/reboot-required ] && echo " !! reboot required"
echo "== Is the fix in the RUNNING kernel's changelog?"
if command -v dpkg >/dev/null; then
dpkg-query -W -f=' package version: ${Version}\n' "linux-image-$KR" 2>/dev/null
zgrep -Eqs "$CVE|$FIX" /usr/share/doc/linux-*"$KR"*/changelog.Debian.gz \
&& echo " PATCHED" || echo " NOT FOUND -> likely VULNERABLE"
command -v pro >/dev/null && pro fix "$CVE" --dry-run </dev/null
elif command -v rpm >/dev/null; then
PKG=$(rpm -qf "/lib/modules/$KR/vmlinuz" "/usr/lib/modules/$KR/vmlinuz" "/boot/vmlinuz-$KR" 2>/dev/null | grep -v 'not owned' | head -1)
echo " package: ${PKG:-unknown}"
rpm -q --changelog "$PKG" 2>/dev/null | grep -Eq "$CVE|$FIX" \
&& echo " PATCHED" || echo " NOT FOUND -> likely VULNERABLE"
if command -v zypper >/dev/null; then zypper -n -q lp -a --cve="$CVE" </dev/null
elif command -v dnf >/dev/null; then dnf -q updateinfo list --all --cve="$CVE" </dev/null
elif command -v yum >/dev/null; then yum -q updateinfo list --cve="$CVE" </dev/null; fi
fi
echo "== Exposure"
sysctl net.mptcp.enabled net.ipv4.tcp_migrate_req 2>/dev/null | sed 's/^/ /'
M=$(ss -lnMH 2>/dev/null); echo " MPTCP listeners (reported root-exploit path): ${M:-none}"
echo " TCP listeners not on loopback (attack surface):"
ss -ltnH | awk '$4 !~ /^(127\.|\[::1\])/ {print " "$4}' | sort -u
EOF
Incollalo per intero: l'EOF finale deve trovarsi su una riga a sé stante senza spazi iniziali.
Lettura dell'output:
| Quello che vedi | Significato | Passo successivo |
|---|---|---|
PATCHED | Il kernel in esecuzione ha già la correzione | Hai finito |
NOT FOUND -> likely VULNERABLE | Nessuna correzione nel kernel in esecuzione | Passo 2 |
!! reboot required, oppure è elencato un kernel più recente di quello in esecuzione | È installato un kernel più recente ma non è ancora in esecuzione | Passo 3 |
A fix is coming soon (Ubuntu) | Ubuntu non ha ancora rilasciato la correzione | Passo 2 ora, Passo 5 dopo |
MPTCP listeners: none | Il percorso di root-exploit segnalato non è applicabile al momento | — |
Una porta di database o cache come *:3306, 0.0.0.0:6379 o 0.0.0.0:11211 | È in ascolto su tutte le interfacce | Assicurati che il firewall la blocchi (vedi la fine del Passo 4) |
La regola seguente scarta i pacchetti TCP IPv4 che trasportano opzioni IP, che è ciò di cui un attaccante ha bisogno per attivare il bug. I client normali (browser, SSH, telefoni, API, load balancer) non inviano mai opzioni IP, quindi il traffico reale non è interessato.
Per prima cosa verifica quale strumento firewall utilizza il server:
systemctl is-active ufw nftables firewalld
Se nftables o firewalld è active, ricaricare quel firewall può cancellare questa regola. Usa la variante nftables alla fine di questo passaggio, oppure adattala alla tua configurazione.
Installa la soluzione temporanea. È una piccola unità systemd, così la regola viene ripristinata dopo ogni riavvio:
sudo tee /etc/systemd/system/cve-2026-98432.service >/dev/null <<'EOF'
[Unit]
Description=Stopgap for CVE-2026-98432: drop IPv4 TCP packets carrying IP options
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/iptables -t raw -I PREROUTING -p tcp -m u32 --u32 "0>>24&0xF=6:15" -m comment --comment CVE-2026-98432 -j DROP
ExecStop=/usr/sbin/iptables -t raw -D PREROUTING -p tcp -m u32 --u32 "0>>24&0xF=6:15" -m comment --comment CVE-2026-98432 -j DROP
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload && sudo systemctl enable --now cve-2026-98432
sudo iptables -t raw -L PREROUTING -v -n
L'ultimo comando dovrebbe elencare una regola DROP con il commento CVE-2026-98432. La colonna pkts conta i pacchetti bloccati; dovrebbe rimanere a 0 o vicino a 0.