
Regole nftables per l'ingress che scartano i SYN TCP IPv4 contenenti opzioni IP per mitigare la use-after-free CVE-2026-98432, con contatori e logging per sorgente.
Mitigazione nftables per CVE-2026-98432: scarta i SYN TCP IPv4 che trasportano opzioni IP, il prima possibile con nftables.
La CVE è una use-after-free nel percorso del request-socket TCP IPv4
(ireq->ireq_opt / inet_opt, letto in ip_options_build()). La correzione
adeguata è un aggiornamento del kernel; questa soluzione riduce solo l'esposizione
finché non se ne dispone uno.
ireq->ireq_opt viene impostato in un solo
punto, tcp_v4_init_req(), a partire dalle opzioni del SYN che apre il request
socket; il SYN ritrasmesso in race legge solo ciò che è stato salvato lì, e lo
scenario della CVE prevede che l'attaccante invii un SYN con le opzioni Record
Route o Timestamp. Quindi un SYN con opzioni è il pacchetto che conta. La
migrazione del request socket riutilizza lo stesso ireq_opt salvato. Questo si
basa sul codice sorgente del kernel e sul testo della CVE, non su una
dichiarazione degli autori della CVE secondo cui il solo SYN è sufficiente;
rimuovere la corrispondenza tcp flags & (syn | ack) == syn dalle regole per la
versione conservativa.
Impostare IFACES sulle NIC che ricevono traffico esterno, poi
sudo nft -f simple.nft. Il ruleset è:
define IFACES = { eth0 }
table netdev cve_2026_98432 {
chain ingress {
type filter hook ingress devices = $IFACES priority -500; policy accept;
ip protocol tcp ip hdrlength > 5 tcp flags & (syn | ack) == syn limit rate 5/second burst 10 packets log prefix "CVE-2026-98432 drop: " level warn
ip protocol tcp ip hdrlength > 5 tcp flags & (syn | ack) == syn counter drop
}
}
netdev ingress con priorità -500 è il primo hook netfilter, prima di
prerouting, conntrack e routing. XDP viene comunque eseguito prima.ip hdrlength > 5 è l'IHL IPv4 in parole da 32 bit; un valore superiore a 5 indica la presenza di opzioni.tcp flags & (syn | ack) == syn è un SYN senza ACK.counter sulla regola di drop è il totale.Monitoraggio: sudo nft list chain netdev cve_2026_98432 ingress e
journalctl -k -g 'CVE-2026-98432'.
fancy.nftfancy.nft è lo stesso drop più un contatore totale con nome e contatori per indirizzo,
mantenuti in due set dinamici. Conta e registra inoltre nel log ogni altro pacchetto TCP che ha
opzioni IP (passato, non scartato), con i byte delle opzioni nella riga di log
(flags ip options, prefisso CVE-2026-98432 ip-options: ):
| Contatore | Dove | Cosa mostra |
|---|---|---|
| totale | contatore con nome dropped_total | SYN con opzioni IP, scartati |
| altri | contatore con nome options_other | altri TCP con opzioni IP, passati |
| per IP sorgente | set by_src | pacchetti e byte per indirizzo sorgente scartato |
| per sorgente . destinazione | set by_pair | lo stesso per coppia (sorgente, destinazione) |
| qualsiasi IP che usa opzioni | set options_by_src | pacchetti e byte per indirizzo sorgente per ogni pacchetto IPv4 con opzioni, qualsiasi protocollo (TCP, UDP, ICMP...), inclusi i SYN scartati |
sudo nft -f fancy.nft
sudo ./cve-log.sh # counters, then follow the kernel log
sudo ./cve-log.sh -c # counters only
sudo ./cve-log.sh -r # reset the total and the per-IP sets
Oppure direttamente:
sudo nft list counter netdev cve_2026_98432 dropped_total
sudo nft list counter netdev cve_2026_98432 options_other
sudo nft list set netdev cve_2026_98432 by_src
sudo nft list set netdev cve_2026_98432 by_pair
sudo nft list set netdev cve_2026_98432 options_by_src
Ogni elemento ha il proprio contatore di pacchetti e byte e scade 1h dopo l'ultimo hit. Ogni set contiene al massimo 65535 voci; quando uno è pieno i nuovi indirizzi non vengono tracciati, ma il pacchetto viene comunque scartato. Gli indirizzi sorgente possono essere falsificati, quindi i contatori per IP mostrano cosa dichiaravano i pacchetti, non chi li ha inviati.
sudo nft delete table netdev cve_2026_98432.
Nessuna delle due persiste dopo un riavvio; includi il file da /etc/nftables.conf.
fancy.nft aggiunge la tabella e ricostruisce solo le regole, quindi ricaricare mantiene i
contatori; esegui prima nft delete table netdev cve_2026_98432 per azzerarli o per
modificare un set. I contatori risiedono nella memoria del kernel e non sopravvivono a un riavvio.