
Atténuation temporaire pour CVE-2026-98432 (use-after-free de ireq_opt dans TCP IPv4 sous Linux) : abandon des paquets TCP IPv4 avec options IP, désactivation de MPTCP. Scripts testés + vérification. EN/KO.
Ce dépôt contient des scripts qui suppriment les paquets TCP IPv4 transportant des options IP sur un hôte Linux. Sur les hôtes dépourvus d'étiquetage CIPSO SELinux/Smack NetLabel, CVE-2026-98432 (une utilisation après libération dans le TCP IPv4 du noyau Linux) ne peut pas se déclencher sans de tels paquets. Il s'agit d'une atténuation temporaire, et non d'un correctif. Elle n'a pas été testée contre un véritable exploit (il n'existe aucun PoC public), et aucun fournisseur ne l'approuve. Si votre distribution fournit déjà un noyau corrigé, installez-le, et exécutez revert.sh si vous avez appliqué cette atténuation. Dans le cas contraire, vérifiez que l'atténuation s'applique à votre hôte, puis appliquez-la et vérifiez-la à l'aide des étapes ci-dessous (environ 10 minutes). L'auteur est un administrateur individuel, et non un fournisseur.
uname -r avec les versions stables corrigées : 5.10.272, 5.15.223, 6.1.190, 6.6.159, 6.12.113, 6.18.56, 7.2.10, 7.3 (commit de correction e3f33b0a1d89d738e2b913dab519226eaf76e15b). Un noyau de distribution peut intégrer le correctif sous un numéro de version différent, alors vérifiez également le suivi de votre fournisseur.cat /sys/kernel/security/lsm. Si SELinux ou Smack est listé et que vous utilisez NetLabel avec un mappage CIPSOV4, cette atténuation ne couvre pas ce chemin.nft. OpenWrt dispose de son propre chemin (voir la section Files). Les hôtes sans systemd, autres qu'OpenWrt, ne sont pas couverts.Gravité : le CNA du noyau attribue un score CVSS de 9.8. Red Hat, Oracle et SUSE attribuent 8.1, et Amazon attribue 7.0. Anthropic a publiquement décrit un exploit root distant contre des serveurs Linux disposant d'un écouteur MPTCP (2026-10-27). Aucune exploitation dans la nature n'a été signalée au 2026-10-29.
État des distributions au 2026-10-29/30 (un instantané, alors vérifiez auprès de votre fournisseur) :
| Distribution | État |
|---|---|
| Ubuntu (toutes les versions prises en charge) | aucun noyau corrigé |
| RHEL 8/9/10 | aucun noyau corrigé |
| Proxmox VE | le journal des modifications de pve-kernel ne comportait aucune entrée pour cette CVE au 2026-10-30 |
| Debian, Oracle Linux UEK, certaines versions de SUSE, certaines versions d'Amazon Linux | correctifs disponibles |
Exécutez sudo ./mitigate.sh. Le script est idempotent (l'exécuter à nouveau recharge le jeu de règles). Il installe les fichiers listés dans la section Files, et il s'arrête si vous n'êtes pas root, si nft est absent ou si systemd est absent.
Comparez la sortie avec la référence ci-dessous. La première ligne doit être :
svc=active enabled=enabled mptcp=0
Les deux règles suivent, l'une dans la table inet et l'autre dans la table bridge.
Si un service écoute avec MPTCP, redémarrez-le. net.mptcp.enabled=0 n'affecte que les nouveaux sockets, donc un listener MPTCP déjà ouvert reste MPTCP jusqu'au redémarrage de son service. Le sysctl est propre à chaque espace de noms réseau, et mitigate.sh ne le définit que pour l'espace de noms de l'hôte.
Si l'hôte exécute des conteneurs LXC ou Docker, poursuivez avec la section Conteneurs.
L'exploit publié ciblait les listeners MPTCP. La course elle-même ne nécessite pas MPTCP (déduction à partir de la description du correctif). La possibilité de compromettre entièrement un hôte sans MPTCP n'est pas établie.
Le SYN-ACK de la cible renvoie les options IP. Un client qui applique lui-même cette mitigation abandonne ce SYN-ACK, donc check-blocked.py signale « blocked » même lorsque la cible n'est pas mitigée. Mesuré sur un hôte : après revert.sh sur la cible, check-blocked.py lancé depuis un client mitigé affichait toujours ipopt FAIL TimeoutError, tandis que verify-synack.sh montrait ipopt synack=5.
Choisissez un outil :
python3 check-blocked.py <host> <port> (pas besoin de root). Il se connecte deux fois : en clair, puis avec une option IPv4 Record Route définie via l'option de socket IP_OPTIONS.sudo ./verify-synack.sh <ip> <port> sur n'importe quel client (root, tcpdump et python3 requis sur le client). Il envoie un SYN en clair et un SYN avec options IP depuis des ports source fixes et compte les SYN-ACK de la cible avec tcpdump.Comparez ensuite la sortie avec le tableau correspondant à cet outil.
check-blocked.py (depuis un client sans la mitigation) :
| Sortie | Signification |
|---|---|
plain CONNECTED | le TCP normal fonctionne |
ipopt FAIL TimeoutError | le SYN avec options IP a été abandonné, comme prévu |
verify-synack.sh :
| Sortie | Signification |
|---|---|
plain: CONNECTED synack=N | ipopt: TimeoutError synack=0 | la cible est mitigée |
ipopt ... synack>=1 | la cible n'est pas mitigée (le SYN avec options IP a reçu une réponse) |
Résultat au niveau du noyau (un hôte Proxmox VE, noyau 7.0, 2026-10-30) : avec la mitigation désactivée, le chemin de code vulnérable s'est exécuté une fois par chemin, via WireGuard et de LXC à LXC. Avec la mitigation activée, le SYN a expiré et le chemin s'est exécuté 0 fois. L'échantillon correspond à 2 chemins dans 2 états sur un seul hôte. La méthode de traçage est décrite dans docs/ANALYSIS.md (en anglais).
L'état nftables est propre à chaque espace de noms réseau, donc les règles de l'hôte seules ne protègent pas les espaces de noms des conteneurs. Mesuré sur des conteneurs LXC : avec uniquement les règles de l'hôte, un SYN avec options IP émis depuis l'intérieur d'un conteneur vers son propre 127.0.0.1 ou vers sa propre IP aboutissait à une connexion. Les conteneurs partagent le noyau de l'hôte, donc du code exécuté dans n'importe quel conteneur pouvait ainsi atteindre le chemin vulnérable.
sudo ./inject-netns.sh sur l'hôte. Il charge le même ensemble de règles dans chaque conteneur LXC en cours d'exécution (via pct/lxc-info, Proxmox) et dans chaque conteneur Docker en cours d'exécution (les conteneurs en mode réseau hôte sont ignorés).| Sortie | Signification |
|---|---|
ok lxc:<id> ou ok docker:<id> | ensemble de règles chargé dans l'espace de noms de ce conteneur |
injected=N failed=M | totaux, M doit valoir 0 |
L'injection n'est pas persistante. Elle est perdue au redémarrage d'un conteneur, donc relancez le script après les redémarrages. Les conteneurs Docker imbriqués dans un conteneur LXC nécessitent l'exécution du script à l'intérieur de ce conteneur LXC (non mesuré).
Résultat mesuré : sur 5 hôtes Proxmox, 64 espaces de noms de conteneurs ont été injectés avec 0 échec. Après l'injection, le même test a expiré et le compteur de rejets de l'espace de noms du conteneur a augmenté.
Le symptôme d'une interférence de cette mitigation est une connexion TCP qui se bloque (expire) plutôt que d'être refusée, accompagnée d'un compteur croissant dans la sortie de :
nft list ruleset | grep counter
| Commande | Effet |
|---|---|
systemctl stop cve-2026-98432-mitigation | désactivé immédiatement, réactivé au redémarrage |
systemctl disable --now cve-2026-98432-mitigation | désactivé maintenant et sur tous les redémarrages |