
Detector em Rust e laboratório local para CVE-2026-98432, um use-after-free de TCP IPv4 no Linux em inet_opt/ireq_opt: análise estática de ELF, verificações de alcançabilidade por kprobe e um gatilho de corrida.
inet_opt / ireq_opt)PoC de pesquisa e laboratório local para um use-after-free no kernel Linux alcançável a partir de um listener TCP IPv4 simples. Este é um detector/gatilho de bug, não um exploit.
7.0.0-38-generic):
inet_sock_destruct() e tcp_v4_reqsk_destructor() liberam as opções com
kfree() em vez de kfree_rcu().kfree é alcançável em tempo de execução (kprobes).free -> use (via=reqsk) em uma execução antiga, e não conseguimos reproduzi-los
de forma confiável.tcp2kaslr também para no gatilho do bug; estágios posteriores
não são publicados.CONFIG_KASAN está desativado e a amostragem do KFENCE está desabilitada.tcp2kaslr)MPTCP não é necessário. O caminho comprovado é TCP IPv4 simples:
ireq_opt).accept() no filho, define SO_LINGER(0) e o fecha.
inet_sock_destruct() libera as opções com kfree().Nosso gatilho anterior estava errado de duas maneiras: a vítima nunca aceitava/fechava o
filho (free_sock=0), e enviávamos um RST em vez de contar com o fechamento pelo servidor.
O código atual adiciona as peças corretas:
listen --accept-close — accept + SO_LINGER(0) + close.--sync — ACK + SYN duplicado concorrentemente, sem RST, opções Record Route.A correção upstream é exatamente:
- kfree(rcu_dereference_protected(inet->inet_opt, 1));
+ kfree_rcu(rcu_dereference_protected(inet->inet_opt, 1), rcu);
e a mesma alteração em tcp_v4_reqsk_destructor().
| Caminho | O que é |
|---|---|
rust-poc/ | o PoC nativo em Rust: análise estática de ELF, kprobes, modos de acionamento |
lab/ | vítima loopback Alpine + PHP para os testes locais antigos |
scripts/ | auxiliares locais de reprodução, auxiliares de auditoria autorizada |
docs/FINDINGS.md | o que foi testado, o que foi confirmado, o que não foi |
docs/EXPLOITATION-NOTES.md | escopo: apenas acionamento do bug, sem RCE |
docs/evidence/ | amostra de evidências sanitizadas |
cd rust-poc
cargo build --release
# static analysis (no root)
./target/release/cve-2026-98432 static
# runtime reachability (root, tracefs)
sudo ./target/release/cve-2026-98432 runtime
# correct local vector: accept+close server + --sync trigger
cd ..
PASSES=1 ./scripts/repro-sync.sh 8083
repro-sync.sh inicia a vítima --accept-close em 127.0.0.1:8083, executa o
gatilho de sincronização com sudo e imprime free_sock, use_build e o
veredito de UAF. Uma execução limpa não é prova de segurança: a taxa é de aproximadamente 1e-7 por
tentativa e os eventos se agrupam.
Se artifacts/ estiver ausente, static/runtime recorrem a /boot; o
script legado scripts/cve-2026-98432.sh --static pode gerar os artefatos do kernel.
Com KASAN, o kernel reporta um slab-use-after-free em
inet_csk_route_req / ip_options_build com a pilha de liberação em
inet_sock_destruct / inet_release. O harness tcp2kaslr chega a isso em
cerca de 134 mil tentativas com KASAN; em um kernel normal, a mesma corrida foi observada apenas
duas vezes em ~48 milhões de tentativas.
Teste apenas kernels e hosts que você possui ou está explicitamente autorizado a testar. O gatilho é uma corrida no kernel e pode travar o host. Use uma VM descartável com um snapshot.
offline-ant/tcp2kaslr — gatilho do bug, evidência de KASAN, análise:
https://github.com/offline-ant/tcp2kaslripv4: free inet_opt and ireq_opt after an RCU grace period
(Eric Dumazet), kfree → kfree_rcu em net/ipv4/af_inet.c e
net/ipv4/tcp_ipv4.c.MIT. Consulte LICENSE.