Aller au contenu
AFRISCON

Linux · Vulnérabilité · nftables · DGSSI

CVE-2026-98432 : comprendre et contenir la faille TCP du noyau Linux

La DGSSI classe critique une faille du code TCP IPv4 du noyau Linux. Le mécanisme, les vérifications, et une mitigation nftables testée en labo en attendant le noyau corrigé.

En bref

  • Le 30 octobre 2026, la DGSSI a classé critique la CVE-2026-98432, une faille du code TCP IPv4 du noyau Linux (Debian, Ubuntu, Red Hat, SUSE, Amazon Linux, Oracle Linux…).
  • C’est un use-after-free : le noyau peut relire les options IPv4 d’un SYN après les avoir libérées. Tout part d’un SYN qui porte des options IPv4.
  • Au 31 octobre, Ubuntu 24.04 est toujours marqué « Vulnerable » ; le correctif est annoncé dans le noyau 6.8.0-149.
  • En attendant, une règle nftables qui rejette les paquets TCP porteurs d’options IPv4 coupe le chemin d’attaque. Nous l’avons testée en labo : les SYN avec options sont rejetés, le trafic normal passe.

Ce que dit l’alerte

Le bulletin DGSSI n° 70343010/26 du 30 octobre 2026 indique que la vulnérabilité « peut permettre à un attaquant non authentifié d’exécuter des commandes en tant que root », avec un risque et un impact critiques. Ubuntu lui donne la priorité High et un score CVSS 3 de 9,8. Aucune authentification n’est nécessaire : il suffit qu’un port TCP soit joignable en IPv4.

Le bulletin renvoie aux pages de chaque distribution. Les tests ci-dessous portent sur un serveur Ubuntu 24.04 LTS exposé sur Internet.

Comprendre la faille

La description publiée avec le correctif est précise. Voici le mécanisme, dans l’ordre.

  1. Quand un SYN arrive, le noyau crée une request socket, une mini-socket qui attend la fin de la poignée de main. Si le SYN porte des options IPv4 (Record Route, Timestamp…), le noyau les copie dans ireq->ireq_opt, pour les renvoyer dans le SYN-ACK.
  2. À la fin de la poignée de main, tcp_v4_syn_recv_sock() crée la socket définitive (la socket « enfant ») et lui transfère ces options (newinet->inet_opt) sans les copier.
  3. Au même moment, un autre cœur peut traiter un SYN retransmis pour la même request socket et renvoyer un SYN-ACK depuis tcp_check_req(). Ce chemin lit les options sous simple rcu_read_lock(), et ip_options_build() lit opt->optlen deux fois.
  4. Depuis le commit 079096f103fa, les request sockets sont traitées sans le verrou de la socket d’écoute. Rien n’empêche donc la socket enfant d’être libérée pendant la construction du SYN-ACK. Or inet_sock_destruct() libère les options avec un kfree() immédiat : ip_options_build() lit alors de la mémoire libérée.

Un second chemin existe avec la migration des request sockets (net.ipv4.tcp_migrate_req=1, ou un programme BPF BPF_SK_REUSEPORT_SELECT_OR_MIGRATE) : la request socket clonée partage les mêmes options, et tcp_v4_reqsk_destructor() les libère elle aussi avec kfree().

Le correctif remplace ces deux kfree() par kfree_rcu() : la mémoire n’est rendue qu’une fois tous les lecteurs sortis. IPv6 n’est pas concerné par le premier chemin, car tcp_v6_syn_recv_sock() duplique les options.

Ce que nous en retenons

Les deux chemins passent par ireq_opt, et ireq_opt n’est rempli que si le SYN reçu porte des options IPv4. Sans options, il reste vide et il n’y a rien à libérer trop tôt. Rejeter les paquets TCP qui portent des options IPv4 coupe donc la condition de départ.

Exploiter la faille demande de gagner une course entre deux cœurs. Ce n’est pas une raison de se rassurer : les distributions et la DGSSI la classent critique, et ce genre de course se rejoue autant de fois que nécessaire, à distance.

Étape 1 : faire l’inventaire

Sur le serveur, nous avons d’abord relevé la version du noyau en service, les noyaux installés et le réglage de migration.

Sortie terminal : noyau 6.8.0-139-generic en service, 6.8.0-147 installé, redémarrage requis, tcp_migrate_req à 0
Le noyau en service est le 6.8.0-139. Le 6.8.0-147 est installé et attend un redémarrage, mais Ubuntu annonce le correctif dans le 6.8.0-149 : redémarrer ne suffit pas, cette fois. tcp_migrate_req vaut 0, la valeur par défaut, donc le second chemin est fermé.

Sur Ubuntu, le client Ubuntu Pro donne le statut exact de la CVE pour la machine, sans rien installer avec --dry-run :

Sortie de pro fix : A fix is coming soon, CVE-2026-98432 is not resolved
Le verdict, en fin de sortie : le correctif n’est pas encore publié pour ce noyau.
Les mêmes vérifications sur vos serveurs
# Ubuntu / Debian
uname -r
sysctl net.ipv4.tcp_migrate_req
pro fix CVE-2026-98432 --dry-run        # Ubuntu, client Ubuntu Pro

# Red Hat, Oracle Linux, Amazon Linux : le correctif est-il dans le noyau installé ?
rpm -q --changelog kernel | grep CVE-2026-98432

Étape 2 : le serveur garde-t-il les options du SYN ?

Pour savoir si la condition de départ est réunie, il suffit d’envoyer un SYN qui porte une option IPv4 et de regarder la réponse. nping (livré avec nmap) le fait avec --ip-options R, qui ajoute une option Record Route. Nous ne déclenchons pas la faille : nous vérifions seulement que le noyau stocke les options.

nping vers le port 443 du serveur : le SYN-ACK revient avec l'option Record Route remplie
Vers le port 443 du serveur (adresse publique masquée). Le SYN-ACK revient avec l’option Record Route remplie : le noyau a stocké les options du SYN pour les renvoyer. C’est exactement le champ ireq_opt que la faille exploite.

Étape 3 : tester la mitigation en labo

Pour éprouver la règle sans toucher au pare-feu de production, nous avons monté un labo isolé sur la même machine, donc sur le même noyau : un namespace réseau relié à l’hôte par une paire veth, avec un petit service web sur le port 8443.

Le labo : un namespace réseau sur le même noyau
ip netns add lab98432
ip link add veth-h98 type veth peer name veth-l98
ip link set veth-l98 netns lab98432
ip addr add 10.98.0.1/30 dev veth-h98 && ip link set veth-h98 up
ip netns exec lab98432 sh -c 'ip addr add 10.98.0.2/30 dev veth-l98 && ip link set veth-l98 up && ip link set lo up'
ip netns exec lab98432 python3 -m http.server 8443 --bind 10.98.0.2 &

# Après les tests
ip netns del lab98432; ip link del veth-h98

Sans règle, le comportement est le même que sur l’adresse publique : le SYN-ACK renvoie les options.

Labo avant la règle : nping et tcpdump montrent un SYN-ACK qui renvoie l'option Record Route
Avant la règle. tcpdump, lancé dans le namespace, montre le SYN avec son option, puis le SYN-ACK qui la renvoie remplie.

La règle

Dans l’en-tête IPv4, le champ IHL donne la longueur de l’en-tête en mots de 32 bits. Sans option, elle vaut 5 (20 octets). Au-delà, le paquet porte des options. La règle rejette donc tout paquet TCP dont l’en-tête dépasse 5 mots :

Fichier nftables : ip hdrlength supérieur à 5 et protocole TCP, compteur, rejet
La règle tient en une ligne. priority raw la place avant le suivi de connexion et avant la pile TCP. Elle est limitée à TCP pour ne pas toucher l’IGMP, qui utilise l’option Router Alert.
Labo après la règle : aucun paquet reçu par nping, le compteur nftables indique un paquet rejeté
Après la règle, le même SYN ne reçoit plus de réponse. tcpdump voit encore arriver le SYN (il capture avant netfilter), mais aucun SYN-ACK ne repart, et le compteur de la règle indique 1 paquet de 80 octets rejeté.
Contrôle : un SYN normal reçoit son SYN-ACK et le service web répond HTTP 200
Contrôle : un SYN sans option reçoit toujours son SYN-ACK, et le service web répond normalement.

Appliquer la règle durablement

Sur un serveur, la règle doit survivre à un redémarrage. Attention au piège classique sur Ubuntu : le fichier /etc/nftables.conf fourni par défaut commence par flush ruleset, qui efface aussi les règles d’ufw ou de fail2ban. Mieux vaut une table dédiée, chargée par sa propre unité systemd :

/etc/nftables.d/drop-ipv4-options.nft
#!/usr/sbin/nft -f
# Mitigation temporaire CVE-2026-98432 : rejeter les paquets TCP porteurs d'options IPv4.
# À retirer une fois le noyau corrigé en service.
table ip ipv4_options_guard
delete table ip ipv4_options_guard
table ip ipv4_options_guard {
  chain prerouting {
    type filter hook prerouting priority raw; policy accept;
    ip hdrlength > 5 meta l4proto tcp counter drop comment "CVE-2026-98432"
  }
}
/etc/systemd/system/ipv4-options-guard.service
[Unit]
Description=Rejet des paquets TCP porteurs d'options IPv4 (CVE-2026-98432)
Before=network-pre.target
Wants=network-pre.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/sbin/nft -f /etc/nftables.d/drop-ipv4-options.nft
ExecStop=/usr/sbin/nft delete table ip ipv4_options_guard

[Install]
WantedBy=multi-user.target
Activer, vérifier, puis retirer après la mise à jour du noyau
systemctl daemon-reload && systemctl enable --now ipv4-options-guard
nft list table ip ipv4_options_guard      # le compteur montre les paquets rejetés

# Une fois le noyau corrigé en service :
systemctl disable --now ipv4-options-guard

Le fichier se recharge sans erreur autant de fois que nécessaire : nous l’avons chargé deux fois de suite dans un namespace de test. Côté effets de bord, les options IPv4 ne servent pratiquement plus sur Internet. Les réseaux étiquetés CIPSO font exception : ils sont rares, mais vérifiez avant d’appliquer.

Étape 4 : le vrai correctif

La règle ne fait que tenir en attendant. Le correctif, c’est le noyau mis à jour.

  1. Surveillez la publication : pro fix CVE-2026-98432 --dry-run sur Ubuntu, ou la page de votre distribution (liens en fin d’article).
  2. Installez le noyau corrigé (apt update && apt full-upgrade sur Ubuntu et Debian), puis redémarrez. Si vous utilisez Livepatch, vérifiez que cette CVE est bien couverte avant de vous passer du redémarrage.
  3. Vérifiez le noyau en service avec uname -r (6.8.0-149 ou plus sur Ubuntu 24.04), puis relancez pro fix : il doit indiquer la CVE comme résolue.
  4. Retirez la règle temporaire.

À retenir

  • La condition de départ est un SYN porteur d’options IPv4. Vérifiez si vos serveurs les stockent avec un SYN de test, depuis l’extérieur.
  • Un noyau installé n’est pas un noyau en service : comparez uname -r à la version corrigée de votre distribution.
  • Une ligne nftables coupe la condition de départ en attendant. Testez-la, gardez son compteur à l’œil, et retirez-la après la mise à jour.
  • Les serveurs exposés sur Internet passent en premier.

Sources

Tests réalisés le 31 octobre 2026 sur un serveur Ubuntu 24.04.5 LTS (noyau 6.8.0-139-generic) et dans un namespace réseau sur ce même noyau. Les captures reprennent les sorties brutes ; seule l’adresse IP publique est masquée.