
Preuve de concept vérifiée par KASAN reproduisant CVE-2026-98432, une utilisation après libération (use-after-free) dans inet_opt/ireq_opt du TCP IPv4 du noyau Linux, avec un harnais de course inter-CPU et un contrôle sur noyau corrigé.
Use-after-free dans inet_opt/ireq_opt du TCP IPv4 du noyau Linux (CVSS 9.8).
Un SYN avec des options d'en-tête IPv4 voit ses options enregistrées sur le socket de requête.
Lorsque la poignée de main se termine, tcp_v4_syn_recv_sock() transmet le même tampon
au socket enfant par pointeur, sans copie. Un SYN retransmis sur un autre CPU
le lit dans tcp_v4_send_synack()/inet_csk_route_req() alors que l'enfant a
déjà disparu (inet_sock_destruct() l'a libéré avec un simple kfree(), les sockets
enfants n'ont pas SOCK_RCU_FREE). Le correctif consiste en deux appels kfree_rcu(), intégrés dans
6.6.159 et versions associées. Vulnérable depuis 4.4.
Le lab démarre un noyau invité afin que le noyau hôte corrigé ne soit jamais la cible :
make image
make kernel-amp kernel-fixed-amp
make rootfs
make test-det-vuln # KASAN: slab-use-after-free in inet_csk_route_req
make test-det-fixed # same attack, clean
phase-det est la reproduction inter-CPU : un flooder de dup-SYN épinglé sur le CPU1 (création du socket
de requête + son timer), les ACK finaux sur le CPU0 (création de l'enfant), accept+close du serveur sur le CPU3 (destruction de l'enfant). RPS désactivé, netns attaquant/cible
sur une paire veth, les paquets sortent en trames Ethernet brutes afin que le noyau de l'attaquant
ne RST jamais la poignée de main. Les noyaux -amp ajoutent un délai de 5 ms
à l'intérieur de inet_csk_route_req entre la prise de ireq_opt et son déréférencement
(injection de délai de type KCSAN, utilisée pour la reproductibilité uniquement dans ces noyaux de
reproduction, clairement signalée dans la source).
poc/poc.c contient aussi les variantes timerace, race, migrate et mptcp.
evidence/REPRODUCED-UAF-first-splat.txt — 12 splats en une exécution, le premier :
[ 9.076253] BUG: KASAN: slab-use-after-free in inet_csk_route_req+0x94/0x370
[ 9.076586] Read of size 1 at addr ffff888002ddaa41 by task poc/85
...
tcp_v4_send_synack+0x212/0x240
tcp_rtx_synack+0xd5/0x280
inet_rtx_syn_ack+0x38/0x60
tcp_check_req+0xb8e/0xde0
tcp_v4_rcv+0x1131/0x15e0
...
Allocated by task 79: tcp_v4_route_req+0x116/0x1b0 (options saved on the SYN)
Freed by task 80: inet_sock_destruct+0x2cd/0x380 (child close(), plain kfree)
evidence/VERIFIED-fixed-kernel-clean.log — même attaque sur le noyau avec
les deux appels kfree_rcu() appliqués : zéro rapport.
Si vous ne pouvez pas encore corriger, supprimez les paquets TCP portant des options IPv4 au prerouting
(ip protocol tcp ip hdrlength > 5 drop), et définissez
net.ipv4.tcp_migrate_req=0 pour la variante de migration. Le vrai correctif est la
mise à jour du noyau.