Fuzzer feito com IA encontra bug de divisão por zero em demuxer VPK do FFmpeg
Um input de 21 bytes crasheia qualquer aplicação baseada em FFmpeg que abra um arquivo .vpk malicioso. A falha é DoS, sem execução de código, e já tem PR de correção.

Um bug de divisão inteira por zero no demuxer VPK do FFmpeg foi reportado em 27 de agosto de 2026 no Forgejo do projeto por Darío Clavijo. A falha permite que um arquivo .vpk (ou stream que se identifique como VPK) de apenas 21 bytes derrube qualquer aplicação que use as bibliotecas do FFmpeg para abrir mídia não confiável. O que chamou atenção da comunidade não foi só o bug em si, mas como ele foi achado: um fuzzer parcialmente escrito com IA.
O que exatamente quebra
A raiz do problema está em libavformat/vpk.c:89, dentro de vpk_read_packet. O demuxer para o formato de áudio VPK (do PS2 da Sony) trata o último bloco do stream de forma especial e divide dois valores por par->ch_layout.nb_channels:
if (vpk->current_block == vpk->block_count) {
unsigned size = vpk->last_block_size / par->ch_layout.nb_channels;
unsigned skip = (par->block_align - vpk->last_block_size)
/ par->ch_layout.nb_channels;
...
}Quando nb_channels é zero, a CPU levanta SIGFPE (exceção de divisão inteira por zero) e o processo morre. Segundo o report, vpk_read_header até valida que nb_channels > 0, mas no caminho de AVIO customizado do fuzzer os dados usados na sondagem (probe) e os dados lidos depois na leitura de pacote podem divergir: last_block_size e block_count acabam calculados com uma contagem de canais válida, enquanto nb_channels volta a zero no momento da divisão.
O input que dispara a falha é este dump de 21 bytes:
00000000 20 4b 50 56 56 50 00 f8 04 00 3b 03 61 39 56 32
00000010 36 36 30 38 50Os primeiros bytes casam com o magic big-endian do VPK, o que faz o avformat_open_input autodetectar o formato e rotear para o demuxer vulnerável. Os bytes em 0x0e–0x11 (00 00 00 00) zeram o número de canais, que é o gatilho.
É grave? Depende do que você processa
O próprio autor classifica a severidade como média e a resume assim na tabela de exploitability do report:
| Fator | Avaliação |
|---|---|
| Determinismo | Determinístico, 21 bytes, um único caminho de código |
| Profundidade do gatilho | Rasa: avformat_open_input detecta o formato pelo magic |
| Pré-condições | Nenhuma: input autocontido, sem rede, sem setup de heap |
| Tipo de sinal | SIGFPE (divisão por zero), não corrupção de memória |
| Segurança de memória | Sem OOB read/write, sem use-after-free, sem NULL deref |
| Alcance | Qualquer app que chame avformat_open_input + av_read_frame em dado não confiável |
Ou seja: é uma primitiva de negação de serviço (DoS), não um caminho direto para execução de código. Não há escrita controlada nem leitura arbitrária adjacente à instrução que falha. Para quem constrói software no Brasil, o recado prático é direto: se o seu backend↳Back-end49 conteúdosIntegração front-end com backend: 7 decisões que evitam caos entre APIs, BFF e GraphQLDev (Back & Front) · abr 2026Como criar uma FAKE API REST para testes — JSONPlaceholderDev (Back & Front) · set 2025Construindo um aplicativo de bate-papo de IA simples com Spring AI e AngularDev (Back & Front) · jul 2025Ver tudo em Dev (Back & Front) → usa FFmpeg (via libavformat) para processar mídia enviada por usuários (thumbnails de vídeo, transcodificação de upload, extração de metadados), um arquivo hostil que se passe por VPK pode derrubar o worker que faz a leitura. Vale lembrar que uploads de mídia são um vetor clássico em plataformas de conteúdo, e o FFmpeg roda por baixo de boa parte desse pipeline.
A correção proposta
A sugestão de fix é um guard no topo de vpk_read_packet, consistente com a validação que já existe em vpk_read_header:
if (par->ch_layout.nb_channels == 0)
return AVERROR_INVALIDDATA;Em vez de SIGFPE, a leitura retorna um erro limpo (-22, AVERROR_INVALIDDATA). O report ainda inclui um teste de regressão com o input de 21 bytes esperando exatamente esse retorno. Na sequência da issue, o membro Jun Zhao apontou que parece ser o mesmo problema já discutido na lista ffmpeg-devel em novembro de 2024 e referenciou um pull request (#24297) que fecha a issue. Se você mantém uma cópia própria do FFmpeg ou tem build travada em versão antiga, é o tipo de patch pequeno que compensa acompanhar até chegar aos branches de release.
O debate: fuzzer com IA vale a pena?
O thread no Hacker News sobre a descoberta girou menos em torno do bug e mais em torno do método. A crítica recorrente é que gerar input inválido é a parte fácil do fuzzing. Como escreveu 12j3afAv:
"Generating an incorrect input file seems to be the easiest task of all for any fuzzer. Generating correct input to get deep into the call stack and then finding something is the hard part."
12j3afAv no Hacker News
Houve também quem reforçasse que o resultado, ainda que modesto, tem valor. Para cpriest, o ponto interessante não é a origem da ferramenta: "The interesting part isn't 'AI↳Inteligência artificial440 conteúdosUX e IA: Transformando Experiências Digitais com Inteligência ArtificialProduto & UX · jan 2025MCP: O que é e por que você vai ouvir falar disso em breve?AI · jul 2025IA generativa e a urgência de reconstruir nossa relação com a verdadeAI · jun 2025Ver tudo em AI → wrote the fuzzer.' It's that a cheap random harness still hits classical bugs in ancient parsers. Keep the corpus; throw away the hype", escreveu no comentário dele. Outro leitor, ks2048, levantou uma questão de higiene de código que atravessa o caso: "[...] can't you just mark all '/' as potential divide by zero errors? I guess sometimes developers think they 'know' some variable won't be zero, but unless it checked explicitly or by the compiler, that shouldn't be trusted", ponderou.
Os números do report dão a dimensão do esforço computacional: o crash apareceu após 495.211 execuções, com um corpus de 13.188 entradas, em 10 h 43 min de fuzzing. É a lógica que dabinat descreve no thread: mandar um agente numa caça a bugs aberta é barato porque, se ele não achar nada, o custo é só tempo de máquina, não tempo de um desenvolvedor pago.
O que fica em aberto
A issue segue em aberto no momento da publicação, com o PR de correção referenciado mas ainda pendente de merge e backport para os branches de release listados no projeto. Fica em aberto também até onde outras versões e demuxers com padrões semelhantes de divisão sem checagem estão expostos, um ponto que a própria observação de que o problema já havia sido discutido em 2024 sugere não ser isolado. Se você depende de FFmpeg para processar mídia de terceiros, o passo prático de hoje é mapear onde libavformat toca input não confiável e acompanhar o release que incorporar o guard.
Fontes: Hacker News · Reações no Hacker News
Este artigo foi escrito por Redação iMasters, um agente de inteligência artificial com revisão editorial humana. Publicado sob revisão editorial de Rafael Chinaglia - iMasters e validação técnica de Tiago Baeta. Saiba como produzimos no expediente.










Comentários
Ninguém comentou ainda. Começa a conversa?