
Regole nftables e unità systemd che scartano i pacchetti TCP IPv4 contenenti opzioni IP per mitigare la use-after-free del kernel Linux CVE-2026-98432 fino al rilascio di un kernel corretto.
Una mitigazione firewall tampone per CVE-2026-98432 su Ubuntu 24.04 (noble), per host che espongono un listener TCP pubblico (ad esempio un nodo Geth sulla porta 30303) mentre un kernel corretto non è ancora disponibile.
CVE-2026-98432 è una use-after-free nel codice di handshake TCP IPv4 del kernel Linux. Quando un SYN in ingresso trasporta opzioni IP IPv4, tali opzioni vengono passate al nuovo socket figlio senza essere copiate; un SYN ritrasmesso elaborato contemporaneamente su un'altra CPU può quindi leggerle dopo che sono state liberate. Esiste un secondo vettore di attivazione tramite la migrazione del request-socket (net.ipv4.tcp_migrate_req=1 o un programma BPF_SK_REUSEPORT_SELECT_OR_MIGRATE).
Ubuntu la classifica come priorità High (CVSS 3: 9.8). Al momento della stesura, la correzione del kernel linux per noble è ancora in corso.
I listener MPTCP non costituiscono un caso separato. I binari Go 1.24+ (inclusi i Geth recenti) aprono i listener come MPTCP per impostazione predefinita, quindi ss li mostra come mptcp. I subflow MPTCP passano attraverso lo stesso percorso SYN TCP IPv4, quindi sono esposti esattamente quanto il TCP semplice. Disabilitare MPTCP (GODEBUG=multipathtcp=0) non mitiga questo problema.
Una singola regola nftables, in una tabella dedicata, scarta qualsiasi pacchetto TCP IPv4 la cui lunghezza dell'header non sia 5 (ovvero qualsiasi cosa che trasporti opzioni IP) prima che lo stack TCP del kernel lo veda:
ip protocol tcp ip hdrlength != 5 counter drop
ip hdrlength != 5) scartava anche le query di appartenenza IGMP, che trasportano l'opzione Router Alert, e può rompere silenziosamente il multicast LAN (mDNS/Avahi, casting).inet cvefix), quindi coesiste con ufw e non viene toccata dai reload di ufw.| File | Installa in | Scopo |
|---|---|---|
nftables-cve-2026-98432.nft | /etc/nftables-cve-2026-98432.nft | Il ruleset (idempotente; sicuro da rieseguire) |
cve-2026-98432.service | /etc/systemd/system/cve-2026-98432.service | Unità oneshot che carica il ruleset all'avvio |
Non inserire questa regola in
/etc/nftables.conf. Quel file inizia conflush ruleset, che cancellerebbe le regole di ufw se viene eseguitonftables.service.
git clone <this-repo> && cd <this-repo>
sudo install -m 0644 nftables-cve-2026-98432.nft /etc/nftables-cve-2026-98432.nft
sudo install -m 0644 cve-2026-98432.service /etc/systemd/system/cve-2026-98432.service
sudo systemctl daemon-reload
sudo systemctl enable --now cve-2026-98432.service
sudo nft list table inet cvefix
Conferma anche che il trigger di migrazione sia disattivato (impostazione predefinita):
sysctl net.ipv4.tcp_migrate_req # expect: 0
Installa nping. Su Ubuntu è incluso nel pacchetto nmap; non esiste un pacchetto nping separato:
sudo apt install nmap
Per prima cosa ricarica il ruleset per azzerare il contatore a 0, poi invia un SYN normale (senza opzioni IP) su loopback:
sudo nft -f /etc/nftables-cve-2026-98432.nft # reload; resets the counter to 0
sudo nping --tcp -p 30303 --flags syn -c 3 127.0.0.1
sudo nft list table inet cvefix
Atteso: risposte SA (SYN-ACK), che mostrano che il listener è ancora raggiungibile, e il contatore resta a packets 0 bytes 0. Se non ricevi risposte, nping potrebbe non riuscire a catturare sul loopback; in tal caso, esegui questo test e il successivo verso l'IP LAN dell'host invece di 127.0.0.1.
Invia lo stesso SYN, questa volta con un'opzione IP (Record Route). Il traffico di loopback passa attraverso l'hook prerouting, quindi questo esercita la regola senza nulla in mezzo:
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 127.0.0.1
sudo nft list table inet cvefix
Atteso: nping non riceve alcuna risposta (Lost: 3 (100.00%)), e il contatore riporta esattamente:
ip protocol tcp ip hdrlength != 5 counter packets 3 bytes 240 drop
(3 probe × 80 byte.)
I test remoti esercitano la regola solo se il probe raggiunge effettivamente l'host. Su un'altra macchina nella stessa LAN, punta all'indirizzo LAN dell'host:
sudo nping --tcp -p 30303 --flags syn --ip-options R -c 3 <host-lan-ip>
Poi controlla il contatore sull'host protetto:
sudo nft list table inet cvefix
Atteso: nessuna risposta, e il contatore aumenta di 3 (a packets 6 bytes 480 se hai eseguito prima il passo 2).
Sondare l'IP pubblico dall'esterno è di solito inconcludente. Molti router e dispositivi ISP rifiutano essi stessi i pacchetti con opzioni IP. Un segno tipico è una risposta RA (reset) con un TTL elevato come ttl=250, che indica un dispositivo con TTL iniziale 255 anziché un host Linux (TTL iniziale 64). La sonda non raggiunge mai l'host, quindi il contatore non si muove. Il passo 4 mostra come distinguerlo.
Esegui questi comandi sull'host protetto.
Conferma che le sonde remote arrivino. Avvia questo comando, poi ripeti la sonda del passo 3 dall'altra macchina:
sudo tcpdump -ni any 'tcp port 30303 and (ip[0] & 0x0f) > 5'
| tcpdump sull'host | contatore nft | risposta nping | Significato |
|---|---|---|---|
| mostra pacchetti | aumenta | nessuna | Mitigazione funzionante |
| mostra pacchetti | invariato | SA | Regola non attiva; verificare nft list table inet cvefix |
| nulla | invariato | nessuna o RA | Sonda interrotta a monte; testare dalla LAN o dal loopback |
Confermare che nient'altro venga intercettato. Lasciare il contatore invariato per diversi minuti; dovrebbe rimanere al valore del test. Per vedere il traffico non-TCP che trasporta opzioni in arrivo (che questa regola lascia intenzionalmente passare):
sudo tcpdump -ni any '(ip[0] & 0x0f) > 5 and not tcp'
Le query IGMP dal router LAN (ad es. igmp query v3 a 224.0.0.1) sono normali e non devono incrementare il contatore.
systemctl is-enabled cve-2026-98432.service # expect: enabled
sudo nft list table inet cvefix # table present
sysctl net.ipv4.tcp_migrate_req # expect: 0
Questa è una soluzione temporanea. Verifica periodicamente la presenza del kernel corretto:
uname -r
sudo pro fix CVE-2026-98432
Quando è disponibile una correzione:
sudo apt update && sudo apt full-upgrade
sudo reboot
Livepatch (tramite un abbonamento personale gratuito a Ubuntu Pro; pro status, canonical-livepatch status) può evitare il riavvio, ma non vi è alcuna garanzia che venga distribuita una livepatch per questa CVE.
Una volta in esecuzione un kernel corretto (mantenerlo è comunque innocuo):
sudo systemctl disable --now cve-2026-98432.service
sudo nft delete table inet cvefix
sudo rm /etc/systemd/system/cve-2026-98432.service /etc/nftables-cve-2026-98432.nft
sudo systemctl daemon-reload
Per un margine aggiuntivo fino alla patch, la porta in ingresso 30303 può essere chiusa completamente (Geth continua a sincronizzarsi tramite i peer in uscita, con meno peer):
sudo ufw deny 30303/tcp
# later:
sudo ufw delete deny 30303/tcp