
Função Ansible e script Python que detectam a exposição do kernel Linux à CVE-2026-98432 e aplicam uma regra nftables que descarta SYNs IPv4 de entrada que transportam opções IP.
Um use-after-free no código TCP IPv4 do kernel Linux
(CVE-2026-98432, CVSS 9.8):
opções IPv4 salvas de um SYN recebido podem ser liberadas enquanto outra CPU
ainda as lê para construir um SYNACK, porque dois caminhos de destrutor as liberam
com um simples kfree() em vez de aguardar um período de carência do RCU.
A correção upstream é
e3f33b0a1d89
("ipv4: free inet_opt and ireq_opt after an RCU grace period").
Em 2026-10-29, nenhum kernel corrigido foi lançado para qualquer série do Ubuntu. Todos os status afetados no rastreador do Ubuntu indicam "work in progress" ou simplesmente vulnerável, e a página não lista nenhuma mitigação. Este pacote é a mitigação.
Ambos os caminhos concorrentes leem ireq->ireq_opt, as opções IPv4 que o kernel salvou
do SYN recebido (tcp_v4_save_options()): a construção do SYNACK as lê
enquanto a destruição do socket filho pode liberá-las, e a migração de request-socket
(net.ipv4.tcp_migrate_req=1, ou um programa
BPF_SK_REUSEPORT_SELECT_OR_MIGRATE) compartilha e depois libera as mesmas
opções. Quando um SYN não carrega opções IPv4, ireq_opt é NULL: não há
nada para liberar e nada para ler. Lemos o commit da correção antes de nos basearmos
nisso; ambas as metades partem de um SYN que carregava opções IPv4.
Assim, o pacote instala uma regra nftables que descarta SYNs TCP IPv4 de entrada que carregam opções IP, em uma tabela própria para nunca colidir com as regras do Docker, do substrato ou da distribuição:
table inet samp_cve_2026_98432 {
chain prerouting {
type filter hook prerouting priority -300; policy accept;
ip hdrlength > 5 tcp flags & (syn | ack) == syn counter drop \
comment "CVE-2026-98432: drop inbound IPv4 SYN carrying IP options"
}
}
Verificado em um kernel real antes do lançamento: um SYN IPv4 com opções atinge o contador e é descartado; um SYN simples passa intacto. O tráfego TCP quase nunca carrega opções IP (vários tipos de opção são descartados por muitas redes como questão de rotina, conforme a RFC 7126), portanto o custo operacional da regra é próximo de zero.
pve,
que a página do Ubuntu não cobre) reportam unknown: leia seus
avisos. A regra em si protegeria qualquer host Linux; as tabelas de veredito
são o que é exclusivo do Ubuntu.A regra vive na memória do kernel e não é persistida em disco. Um
pacote de mitigação não deve escrever em caminhos de persistência (units, cron), e um
arquivo de include do nftables só é carregado onde o serviço nftables da distribuição
está habilitado, o que nestes ambientes não é uniforme. Portanto: após
uma reinicialização, uma detecção lê a regra ausente (rule_live=0,
persistent=0 em cada linha de resultado) e a próxima aplicação a restaura.
Reexecutar a aplicação após reinicializações é o modelo operacional, e a linha de resultado
nunca afirma o contrário.
Somente leitura, prepara-se em um diretório temporário privado que remove, e reporta:
uname -r, mapeado para sua versão de pacote)
contra as versões corrigidas do Ubuntu por release e flavour. Nenhuma correção lançada
para o release da máquina: no_fix. Um kernel corrigido lançado mas não
em execução: vulnerable, com restart_needed=1 quando está instalado e
aguardando uma reinicialização (uma correção instalada nunca é reportada como fixed).fixed com workaround: true na
linha de resultado enquanto a regra cobre um kernel não corrigido; fixed simples
assim que o kernel em execução estiver corrigido.not_affected para releases que o tracker libera, unknown para releases
e distribuições que as tabelas não cobrem.0 limpo (fixed, not_affected), 2 exposto ou
indefinido (no_fix, vulnerable, unknown: nunca limpo), 1 a execução
em si falhou, 130 interrompida.syn_options_mitigation/files/samp_common.py é uma cópia byte a byte de
samp-common 1.0.4 (as comparações de versão dpkg, rpm e apk,
a linha de resultado, o carregamento de configuração). Seu sha256 está em
samp.yaml, e tests/test_samp_pack.py falha se a cópia diferir. Nunca
edite-a aqui; re-vendorize-a com o scripts/vendor.py do samp-common.samp/v<version> (esta:
samp/v1.0.1), assinadas com uma chave com suporte de hardware. O substrato
importa uma tag assinada, nunca um branch.Um passo de script, uma linha de resultado. Enquanto o kernel em execução não estiver corrigido, ela
carrega a regra; assim que um kernel corrigido estiver em execução, ela remove a regra e
sua tabela. Não edita nenhum arquivo além do script, biblioteca e configuração que
implanta (declarados em samp.yaml touches), portanto a lista de backup da linha de resultado
está vazia. Remover a mitigação manualmente é um comando:
nft delete table inet samp_cve_2026_98432
ansible-playbook -i inventory play.yml # a play that runs the role
python3 syn_options_mitigator.py --config syn_options_config.yaml # detect
sudo python3 syn_options_mitigator.py --config syn_options_config.yaml --apply
Quando o Ubuntu lançar kernels corrigidos, cole as versões do tracker
em syn_options_fixed_versions nos padrões da role (as versões
em andamento já estão lá em um comentário) e publique a alteração como a próxima
tag assinada; a detecção então começa a reportar vulnerable/restart_needed
em relação a elas, e o apply remove a regra das máquinas que reiniciam em um
kernel corrigido.
python3 -m pytest tests/
Os testes unitários simulam todos os comandos externos; o teste de contrato
(tests/test_samp_pack.py, do samp-common) verifica o manifesto em relação à
role, executa uma detecção real a partir de um diretório temporário e mantém a entrada de apply
sujeita às regras de linha de resultado única e de needrestart.
MIT. Consulte LICENSE.
PRs e melhorias são bem-vindos -> faça um fork e envie um merge request.