Sonda remota de caixa-preta que detecta a CVE-2026-98432, um use-after-free em ireq_opt do TCP IPv4 do Linux, por meio de eco diferencial de opções SYN-ACK, além de verificação estática de vmlinux.
Olá. A CVE-2026-98432 é uma Use-After-Free explorável remotamente no Kernel Linux. Alguns relatos afirmam que laboratórios de IA a exploraram após ~45min via Multi-Path TCP (MPTCP). A vulnerabilidade está, na verdade, na própria pilha TCP IPv4; é só que o MPTCP é a única forma, mesmo remotamente, de chegar ao caminho de código vulnerável. Mesmo assim, ~45min merece um escrutínio bem aprofundado.
ireq_opt e a primeira desreferência.Certamente existem kernels Linux customizados que usam MPTCP com opções de direcionamento por pacote que provavelmente tornam essa vulnerabilidade "alcançável" no sentido mais puro. Na prática, você quase certamente não está executando tal configuração de kernel, e também não é tão azarado a ponto de alguém estar próximo o suficiente em latência e persistente o suficiente para acertar essa lacuna.
O principal fator que torna a exploração mesmo remotamente prática são VMs virtualizadas/sobrecarregadas, com PREEMPT_RT, threadirqs, etc... o que não é algo sobre o qual um atacante tenha qualquer controle ou influência, a menos que tenha algum acesso privilegiado/autenticado adicional. Tenho alguns amigos na indústria que provavelmente conhecem um truque ou outro que mudaria minha opinião, mas não conheço nada, a IA ficou sem resposta, e, no mínimo, esse "truque", se existir, não é amplamente conhecido.
Você deve aplicar patches nos seus servidores, mas provavelmente não entrar em pânico por causa disso. Todo o resto neste repositório, incluindo as linhas abaixo, é gerado por IA, mas eu conduzi a sessão e revisei os artefatos quanto à precisão.
A seguir:
Uma sonda remota de caixa-preta que demonstra a presença da CVE-2026-98432
(use-after-free de ireq_opt / inet_opt no TCP IPv4 do Linux) com evidências
em nível de pacote — não por correspondência de versões de kernel.
Ela para no use-after-free: prova que o kernel leu memória liberada e disse isso no fio. Não contorna o KASLR, não sequestra o fluxo de controle nem executa código.
Apenas para testes autorizados. A sonda de corrida pode desestabilizar um alvo; um kernel travado é um desfecho plausível. Use-a apenas em hosts que você possui ou para os quais tem permissão por escrito para testar.
A correção é e3f33b0a1d89d738e2b913dab519226eaf76e15b
(ipv4: free inet_opt and ireq_opt after an RCU grace period), uma mudança de duas linhas
de kfree() para kfree_rcu() em inet_sock_destruct() e
tcp_v4_reqsk_destructor().
tcp_v4_init_req() armazena as opções IP ecoadas do SYN (Record Route /
Timestamp) em ireq->ireq_opt.tcp_v4_syn_recv_sock() transfere o ponteiro para o socket filho em vez
de copiá-lo.ireq->ireq_opt sob
rcu_read_lock() e o usa em ip_options_build().Esse último ponto é o detector: o kernel ecoa os bytes obsoletos da opção de volta para o remetente.
Correção de escopo: o registro da CVE é TCP IPv4 genérico. Apenas o blog da Anthropic o associa a um "multipath TCP listener"; nenhum texto da CVE/NVD/Red Hat/Debian/Ubuntu menciona MPTCP. A sonda testa primeiro TCP simples.
Três pernas independentes, da mais fraca à mais forte:
| Etapa | O que demonstra | Artefato |
|---|---|---|
| Estática (fixada por build-id) | a forma do código do kernel em execução: kfree simples em ambos os destrutores = vulnerável; kvfree_call_rcu = corrigido | verify-local, tabela abaixo |
| Oráculo sintético | o detector de rede dispara quando um responder ecoa memória de slab reutilizada | scripts/validate_synthetic.sh → CONFIRMED VULNERABLE |
| Dinâmica, em nível de kernel (laboratório KVM) | o KASAN reporta o slab-use-after-free real em ip_options_build, com as pilhas do commit; um kernel com kfree_rcu e tráfego idêntico permanece limpo | evidence/guest-inst-vuln6-KASAN.log, evidence/guest-inst-patched2-CONTROL.log |
| Visível na rede, kernel real (laboratório sem KASAN) | o SYN-ACK na rede carregava o bloco de opções pulverizado (42 04 be ef…) em vez do timestamp ecoado; o controle com kfree_rcu permaneceu limpo | evidence/race-stage1-wire-uaf.json, evidence/race-control-kfree_rcu.json |
A etapa dinâmica é um guest 7.0.14 construído especificamente para o efeito (KASAN + uma ampliação da janela via parâmetro de boot) com direcionamento de CPU por pacote: o SYN retransmitido é processado em uma vCPU, o ACK/transferência em uma segunda, e o accept()+close() da vítima em uma terceira, de modo que a sobrescrita é rotineira em vez de acidental. O próprio kernel reportou:
BUG: KASAN: slab-use-after-free in ip_options_build
Read of size 16 ... by task swapper/0 (cpu0, softirq)
__asan_memcpy <- ip_options_build <- ip_build_and_send_pkt
<- tcp_v4_send_synack <- tcp_rtx_synack <- tcp_check_req <- tcp_v4_rcv
Freed by task 1 (victim, cpu3):
kfree <- inet_sock_destruct <- __sk_destruct <- inet_release <- __x64_sys_close
object: kmalloc-96, 16 bytes in (struct ip_options at the rcu_head offset)
mais 30 registros READ-AFTER-FREE do lado do leitor (leitura 71–322 µs após o free, optlen=40, sombra KASAN 0xfb). O controle corrigido (kfree_rcu, verificado no arquivo objeto) executou a mesma corrida e retenção: 0 KASAN, 0 read-after-free. Essa é a vulnerabilidade, não um palpite de versão.
O leitor não é um loop longo. tcp_v4_send_synack() carrega ireq->ireq_opt e o passa para ip_build_and_send_pkt()/ip_options_build(), cujo memcpy é a leitura use-after-free; o carregamento e a leitura estão a poucas instruções de distância (dezenas a centenas de nanossegundos). O lado do free — destruição do filho após o accept()+close() da vítima — ocorre muito depois: o ciclo de close medido isoladamente é de 61–92 µs, e a latência ACK→destruição acrescenta o despertar entre CPUs.
Portanto, os dois eventos não são apenas raros juntos; eles estão separados por ~90 µs por construção, e a leitura termina muito antes do free. O experimento de temporização natural quantifica isso: com o mesmo kernel instrumentado, sem alongamento de janela, ~140k tentativas de corrida e uma rotatividade concorrente de half-open,
stats: frees=180223 overlaps=0 raf=0 KASAN: 0