PwnEscape: o que está confirmado sobre o CVE-2026-99999, a falha crítica que atravessou o limite guest-host no Linux
Um checksum IPv4 adiado. Um cabeçalho que muda depois de já ter sido validado. Um vazamento de memória do host que, em laboratório, virou uma primitiva de escape guest-to-host.
Em 15 de outubro de 2026, o CNA do Linux publicou o CVE-2026-99999, uma vulnerabilidade crítica no stack de rede do kernel Linux. A falha ficou conhecida como PwnEscape e foi encontrada por Paulos Yibelo, da pwn.ai, durante o desafio de US$ 1 milhão da Vercel Sandbox.
Apesar do número incomum, o registro é oficial: está publicado no MITRE/CVE e indexado no NVD. E, apesar do apelido "KVM escape", o defeito não está no KVM. Está no tratamento de checksum e fragmentação IPv4 do kernel do host.
Este post reúne apenas o que está documentado em fontes primárias até 19 de outubro de 2026, separando o que foi demonstrado, o que foi corrigido e o que ainda não é público.
Ficha técnica
| Campo | Valor |
|---|---|
| CVE | CVE-2026-99999 |
| Nome | PwnEscape |
| Tipo | Falha de validação de metadados de checksum no IPv4; corrupção de cabeçalho e leitura fora dos limites lógicos do sk_buff |
| Componente | Kernel Linux — stack de rede (net/ipv4, netfilter, bridge, XFRM) |
| CNA | Linux |
| Pesquisador | Paulos Yibelo (pwn.ai) |
| CVSS 3.1 | 9.3 — Crítico |
| Vetor | CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H |
| Publicação | 15 de outubro de 2026 |
| Reserva do ID | 25 de setembro de 2026 |
| Correção upstream | commit 6785011f8b16abf40b1e9d8b2e332232b3e68822 |
| Autor do patch | Michael S. Tsirkin (Red Hat) |
| Status NVD | Received (registro presente, ainda sem enriquecimento completo do NVD em 19/10/2026) |
O vetor chama atenção por combinar AV:L (vetor local) com S:C (escopo alterado) e impacto alto nos três pilares. O próprio registro explica: o caminho não é a recepção comum de pacotes pela internet, e sim a interface de rede virtual de uma microVM. O atacante está no guest; o efeito ocorre no kernel do host.
O resumo em nove pontos
- O kernel Linux carrega pacotes com checksum adiado (
CHECKSUM_PARTIAL) e só completa o cálculo depois, muitas vezes em outro ponto do stack. - A posição de início da acumulação (
skb->csum_start) e o deslocamento (skb->csum_offset) definem onde o checksum será escrito; esses metadados podem ser controlados pelo guest viavirtio-net. - Em
ip_do_fragment(), o kernel completava o checksum antes de reler o cabeçalho IPv4 e o campoihl(tamanho do cabeçalho). - Com metadados malformados, a escrita do checksum podia atingir o próprio cabeçalho IPv4 já validado e alterar o
ihlde 20 para 60 bytes. - O fragmentador passava a confiar no novo tamanho e copiava 40 bytes além do cabeçalho original. Desses, 32 bytes vinham de memória do host, não do pacote enviado pelo guest.
- O resultado era um vazamento repetível de memória do host dentro de pacotes IPv4 de saída.
- Em ambiente próprio de pesquisa, a pwn.ai demonstrou ainda escritas selecionadas de 64 bytes no kernel do host e uma execução de helper com privilégios de root, em quatro boots a frio.
- A Vercel confirmou o vazamento de memória contra sandboxes de produção. Os ataques de crash e execução de código foram demonstrados em máquinas KVM e Firecracker do próprio pesquisador, compatíveis com a configuração do Vercel Sandbox — não em produção da Vercel.
- O fix upstream adiciona uma validação de
csum_startantes da conclusão do checksum em cinco consumidores do stack.
O bug: quando o checksum escreve no lugar errado
Para entender o PwnEscape, é preciso entender duas coisas que o kernel faz o tempo todo sem drama: checksum offload e fragmentação IPv4.
O Linux não precisa calcular imediatamente o checksum de transporte de todo pacote. Ele pode carregar um sk_buff em estado CHECKSUM_PARTIAL, com a promessa de completar o cálculo mais tarde. Três campos importam:
skb->ip_summed = CHECKSUM_PARTIAL // checksum ainda pendente
skb->csum_start = onde a acumulação começa
skb->csum_offset = deslocamento até o campo de saída
destino da escrita = csum_start + csum_offset
Em tráfego bem formado, esse destino é o campo de checksum de TCP ou UDP. O problema é que esses valores autorizam uma escrita posterior na memória do pacote. Se software menos confiável consegue influenciá-los, a validação precisa continuar verdadeira até o momento da escrita.
E há uma complicação: o pacote passa por transformações. Cabeçalhos de enlace são removidos, o skb->data avança, o network_header é ajustado. Uma posição que parecia suficientemente à frente no quadro original pode não estar à frente do cabeçalho IPv4 que o kernel vai usar depois.
No caminho vulnerável, a ordem era esta:
/* Trecho histórico, simplificado */
if (skb->ip_summed == CHECKSUM_PARTIAL)
skb_checksum_help(skb); /* escrita adiada acontece aqui */
iph = ip_hdr(skb);
/* a fragmentação passa a usar iph->ihl */
Ou seja: o checksum era completado antes de o código reler o cabeçalho IPv4 e seu tamanho. Se csum_start apontasse para dentro do cabeçalho já validado, a escrita do checksum podia alterar um campo que o kernel já tinha analisado e autorizado.
O campo escolhido foi o ihl, um contador de 4 bits que define o tamanho do cabeçalho IPv4 em palavras de 32 bits. No caso controlado da pesquisa, o primeiro byte do pacote mudou de:
0x45 -> IPv4, IHL = 5 -> cabeçalho de 20 bytes
0x4f -> IPv4, IHL = 15 -> cabeçalho de 60 bytes
O nibble de versão continuou 4. Apenas a interpretação do tamanho mudou — e mudou depois de as decisões de parsing, políticas e roteamento terem sido tomadas com base nos 20 bytes originais.
A pwn.ai descreve isso como um TOCTOU semântico: não é uma corrida entre threads, e não depende de timing. A "janela" é a sequência determinística de operações legítimas de rede, com uma escrita adiada no meio. O kernel confiou em duas versões diferentes do mesmo pacote.
De onde vieram os 32 bytes
O sk_buff não precisa manter todos os bytes do pacote de forma linear. Ele tem um head linear e possíveis fragmentos não lineares.
No caso estudado, o head linear lógico tinha:
20 bytes cabeçalho IPv4 original
8 bytes payload disponível no primeiro fragmento
--------
28 bytes total no head linear lógico
Depois da mutação, o fragmentador acreditava que o cabeçalho tinha 60 bytes. Ele copiou os 60 bytes para os "opções IPv4" do pacote de saída. Desses, 20 eram o cabeçalho original e 8 eram payload legítimo. Os 32 bytes restantes não faziam parte dos dados lógicos do pacote — vinham da memória do host.
A pwn.ai faz uma distinção importante: isso é uma leitura fora dos limites lógicos do sk_buff, não necessariamente um acesso além do objeto físico de alocação. O host podia ter tailroom mapeado logo após skb_headlen(). Ler esses bytes e colocá-los em um cabeçalho transmitido ainda cruza a fronteira de confidencialidade: são bytes do host, não bytes que o guest enviou.
O pacote de saída, então, expunha a memória como se fossem opções IPv4. O vazamento saía do estado interno do kernel e virava um artefato observável na rede.
Do vazamento ao escape
O primeiro impacto confirmado é divulgação de memória do host. A Vercel confirmou que o ataque de vazamento foi demonstrado contra sandboxes de produção da Vercel Sandbox. Segundo a empresa, a memória do host aparecia em pacotes enviados pelo guest, de forma contínua enquanto ele continuasse enviando tráfego.
O segundo impacto é disponibilidade: a Vercel relata que dois pacotes foram suficientes para derrubar a máquina host, encerrando todas as sandboxes nela. Esse teste foi feito em KVM e Firecracker do pesquisador, com configuração equivalente à do Vercel Sandbox.
O terceiro impacto é execução de código no host. A pwn.ai descreve uma cadeia de laboratório em que, a partir das observações de memória do host e de um controle cuidadoso de alocação, demonstrou escritas selecionadas de 64 bytes no kernel do host. Essas escritas foram usadas para executar um helper com privilégios de root e devolver ao guest um marcador gerado pelo host. O experimento foi repetido em quatro boots a frio reais, em máquinas próprias.
Aqui é necessário ser preciso sobre o que cada fonte afirma:
| Alegação | Onde foi demonstrado | Status |
|---|---|---|
| Vazamento de memória do host | Sandboxes de produção da Vercel | Confirmado pela Vercel |
| Crash do host com dois pacotes | KVM/Firecracker do pesquisador, configuração equivalente | Demonstrado em laboratório |
| Escrita no kernel do host e execução de código root | KVM/Firecracker do pesquisador | Demonstrado em laboratório; detalhes completos prometidos para a Parte 2 |
| Acesso a dados de clientes na Vercel | — | A Vercel afirma que nenhum relatório mostrou acesso a dados de clientes |
A pwn.ai é explícita: não se trata de uma inferência a partir de uma leitura fora dos limites, e também não é uma alegação de execução de comandos root em ambiente de produção de nenhum fornecedor. O que foi provado em produção foi o vazamento; o restante foi provado em máquinas controladas pelo pesquisador.
Também não é correto dizer que o KVM foi explorado. A falha está no kernel Linux do host, no processamento de rede. O limite guest-host é atravessado porque o kernel do host processa metadados originados no guest. No cenário descrito, o hypervisor e o modelo de dispositivo apenas entregam o tráfego; a falha ocorre no processamento do kernel do host.
Quem está afetado
O registro do CVE lista o kernel Linux como afetado a partir da versão 2.6.27, com correções por ramo. As primeiras versões corrigidas indicadas no registro são:
| Ramo | Versão corrigida |
|---|---|
| 5.10 | 5.10.272 |
| 5.15 | 5.15.223 |
| 6.1 | 6.1.190 |
| 6.6 | 6.6.159 |
| 6.12 | 6.12.113 |
| 6.18 | 6.18.57 |
| 7.2 | 7.2.11 |
| 7.3 | 7.3 (mainline) |
O cenário de risco não é qualquer máquina Linux recebendo pacotes da internet. O próprio CVSS usa AV:L e o registro descreve o caminho como uma interface de dispositivo virtual: o guest envia um quadro com metadados de checksum forjados; o VMM grava no TAP do host; tun_get_user() entrega o skb ao stack IPv4; e ip_do_fragment() chama skb_checksum_help().
Por isso o grupo mais exposto é o de provedores de sandbox, plataformas de microVM, ambientes multi-tenant e qualquer host que execute cargas não confiáveis com rede virtual. Nesses ambientes, o kernel do host é infraestrutura compartilhada: um guest malicioso não deveria conseguir ler memória, derrubar o host ou escrever no kernel a partir de metadados de checksum.
O CISA publicou um SSVC em 16 de outubro de 2026 com:
- Exploitation: none
- Automatable: no
- Technical Impact: total
Ou seja: até aquela data, não havia exploração conhecida em circulação, e o ataque não era considerado automatizável. Isso não significa que seja difícil para um atacante motivado — a pwn.ai descreve a mutação do cabeçalho e o vazamento como determinísticos e repetíveis —, mas significa que não havia, até 16/10, evidência pública de uso em massa ou in-the-wild.
A correção
O patch aceito na mainline é de Michael S. Tsirkin, com revisão de Willem de Bruijn e assinatura de Jakub Kicinski:
commit 6785011f8b16abf40b1e9d8b2e332232b3e68822
ipv4: validate checksum_start before completing checksum
Ele adiciona um helper em include/net/ip.h:
static inline int ip_check_csum_start(const struct sk_buff *skb)
{
if (unlikely(skb->csum_start <
skb->network_header + ip_hdrlen(skb)))
return -EINVAL;
return 0;
}
A invariante é simples:
csum_start >= network_header + ip_hdrlen(skb)
Com um csum_offset não negativo, isso garante que o destino final da escrita (csum_start + csum_offset) não cai dentro do cabeçalho IPv4. O check não tenta provar que o destino é o campo de checksum correto de TCP ou UDP; ele protege apenas o cabeçalho IPv4 que já foi validado.
O guard é aplicado antes de skb_checksum_help() em cinco consumidores:
ip_do_fragment(), emnet/ipv4/ip_output.c;nf_br_ip_fragment(), emnet/bridge/netfilter/nf_conntrack_bridge.c;nf_queue_checksum_help(), emnet/netfilter/nfnetlink_queue.c;checksum_tg(), emnet/netfilter/xt_CHECKSUM.c;xfrm_output(), emnet/xfrm/xfrm_output.c.
São seis arquivos alterados no total, contando o helper. O commit é explicitamente descrito como defesa em profundidade, não como uma reescrita completa da API de checksum do virtio. A mensagem diz que uma validação de entrada mais completa ainda está por vir e exige mais trabalho.
O patch também carrega:
Fixes: f43798c27684 ("tun: Allow GSO using virtio_net_hdr")
Fixes: bfd5f4a3d605 ("packet: Add GSO/csum offload support.")
Reported-by: Paulos Yibelo <habte.yibelo@gmail.com>
Ou seja, a origem do problema é antiga: os caminhos de GSO/checksum offload do TUN e do AF_PACKET. As oito referências de commit estável no registro cobrem os backports para os ramos listados.
Linha do tempo
| Data (2026) | Evento |
|---|---|
| 18 de agosto | Vercel anuncia o desafio de US$ 1 milhão para quebrar o isolamento do Vercel Sandbox. |
| 20 de agosto | pwn.ai envia o relatório inicial de vazamento de memória do host. |
| 4 de setembro | pwn.ai relata a causa raiz ao contato de segurança do kernel e aos mantenedores de rede, com patches candidatos. |
| 7 de setembro | Michael S. Tsirkin reproduz o problema e reconhece os patches. |
| 19–22 de setembro | Submissões públicas no netdev expandem a revisão da invariante de cabeçalho de rede e de caminhos relacionados. |
| 25 de setembro | CVE-2026-99999 é reservado. |
| 7–8 de outubro | O guard revisado é postado e aceito em net.git. |
| 13–14 de outubro | Revisão estável e coordenação do CVE continuam. |
| 14 de outubro | Vercel publica o balanço do desafio: 1.285 relatórios, US$ 242 mil em bounties e uma falha zero-day no kernel Linux. |
| 15 de outubro | CVE é publicado; a mensagem no oss-security divulga o caso. |
| 16 de outubro | CISA publica o SSVC. |
| 19 de outubro | Registro do CVE é atualizado. |
O que isso ensina
A lição técnica vai além do IPv4. O padrão que a pwn.ai chama de deferred-metadata trust inversion é este:
metadado não confiável entra
|
v
é validado contra uma representação inicial
|
v
o pacote é normalizado, parseado e autorizado
|
v
uma operação adiada, guiada pelo metadado, roda depois
|
v
bytes relevantes para a segurança mudam
|
v
um consumidor posterior confia na nova interpretação
|
v
falha de memória ou de fronteira de política
A pergunta de auditoria não é apenas "os offsets de checksum foram validados?". É: "depois de cada transformação, uma escrita adiada ainda pode atingir bytes cujo significado já foi confiado?"
O fix do Linux responde a essa pergunta para o cabeçalho IPv4. Ele não prova que todo destino de checksum de cada protocolo está correto, e a própria pwn.ai ressalva que preocupações sobre mutação posterior de campos de transporte após checagens de política são riscos relacionados, mas distintos. Não devem ser somados ao vazamento de 32 bytes nem tratados como totalmente resolvidos por este patch.
Para quem constrói sandboxes, a conclusão é desconfortável: o isolamento não vive só no hypervisor. O guest interage com um sistema operacional inteiro — emulação de dispositivos, rede virtual, filtros, alocadores, APIs. Cada contrato de performance que atravessa a fronteira precisa carregar suas invariantes até o último consumidor.
O que fazer
- Atualize o kernel do host para uma das versões corrigidas ou posterior. Em ambientes com kernel de distribuição, aplique o backport do fornecedor quando disponível.
- Priorize hosts que executam cargas não confiáveis. Sandboxes, microVMs, CI remoto, plataformas multi-tenant e serviços que rodam código de terceiros são o alvo natural.
- Não existe workaround oficial documentado no registro do CVE. A correção é o patch. Qualquer mitigação paliativa deve ser avaliada com o fornecedor do kernel ou da plataforma.
- Não confunda "sem exploração conhecida" com "não explorável". O SSVC de 16/10 registrava
Exploitation: none, mas o pesquisador demonstrou a mutação e o vazamento em laboratório e descreveu a sequência como determinística. - Acompanhe os avisos do seu fornecedor. O NVD ainda estava em status
Receivedem 19/10; a fonte mais completa até agora é o registro do CNA Linux no MITRE/CVE.
O que está confirmado — e o que ainda não está
Confirmado por fontes primárias
- O CVE-2026-99999 existe, foi publicado pelo CNA Linux em 15/10/2026 e tem CVSS 9.3 (Crítico).
- A falha está no kernel Linux, no tratamento de
checksum_starte fragmentação IPv4, e não no KVM. - O pesquisador foi Paulos Yibelo, da pwn.ai, no contexto do desafio da Vercel Sandbox.
- O vazamento de memória do host foi demonstrado contra produção da Vercel.
- Crash do host e execução de código root foram demonstrados em KVM/Firecracker do pesquisador, não em produção da Vercel.
- A Vercel afirma que nenhum relatório mostrou acesso a dados de clientes.
- O fix upstream é o commit
6785011f8b16, com backports para os ramos listados. - O CISA SSVC de 16/10/2026 indica
Exploitation: none,Automatable: no,Technical Impact: total.
Ainda não público ou não confirmado
- A cadeia completa de escrita no kernel e execução de código root: a pwn.ai prometeu detalhes na Parte 2.
- Quais outros hypervisors ou provedores foram afetados: a pwn.ai diz que o problema existe em "muitos outros ambientes de hypervisor", mas não nomeia todos.
- Exploração in-the-wild: não havia evidência pública até 16/10/2026.
- Cobertura total de todos os consumidores e protocolos: o patch é defesa em profundidade e a validação de entrada mais ampla ainda estava pendente.
- Enriquecimento completo do NVD: o status era
Receivedem 19/10/2026.
Três nuances que costumam se perder
- O número 99999 não é um placeholder. É um ID válido, atribuído pelo CNA do Linux, com registro publicado e referências de patch.
- "KVM escape" descreve a fronteira cruzada, não o arquivo do bug. O defeito está no stack de rede do kernel do host.
- Não é uma falha remota pela internet. O vetor é local/guest. No cenário confirmado, o atacante precisa enviar tráfego por uma interface de rede virtual (virtio-net/TAP) com metadados de checksum controlados.
Fontes primárias
- Registro CVE (MITRE/CVE Program): CVE-2026-99999
- NVD: CVE-2026-99999
- Balanço do desafio (Vercel): Findings from the $1M Vercel Sandbox challenge
- Divulgação no oss-security: linux kernel: PwnEscape: Guest-to-Host KVM Escape (CVE-2026-99999)
- Patch upstream: commit 6785011f8b16
- Patch completo (diff): 6785011f8b16.patch
- Discussão inicial no netdev: lore.kernel.org/netdev/20260922030310.8684-2-habte.yibelo@gmail.com
- Documentação de checksum offload do Linux: kernel.org — Checksum Offloads