· via dev.to (home feed)
AI-built fuzzer finds 21-byte division-by-zero crash in FFmpeg's VPK demuxer
A 21-byte crafted VPK audio file triggers a division by zero in FFmpeg's Sony VPK demuxer, crashing apps that feed it through custom I/O. The bug surfaced via an AI-assisted fuzzer after roughly 495,000 executions.

A 21-byte denial of service
A security researcher has reported a 21-byte input that crashes FFmpeg-based applications through a division by zero in the demuxer for an obscure Sony audio format. The flaw, filed as issue #24290 on the FFmpeg tracker, was found by Darío Clavijo using a fuzzer he built largely with AI assistance, and the story is documented in a detailed dev.to write-up by jamilxt.
The bug lives in libavformat/vpk.c, the demuxer for Sony PS2 VPK audio files, a container format almost nobody encounters. That obscurity is central to why it survived. The crash chain, per the tracker entry, runs as follows:
- FFmpeg's format probing matches the VPK magic bytes and assigns the VPK demuxer.
- vpk_read_header parses a 24-byte header. The crafted input sets the channel count, nb_channels, to zero at bytes 14 through 17. The header code does validate that the count is positive, but under the fuzzer's custom I/O setup the data seen during probing and the data seen during packet reading can diverge.
- By the time vpk_read_packet handles the final audio block, nb_channels is zero again, and a division at line 89 by that value raises SIGFPE and kills the process.
The issue's crash metadata: 495,211 executions to find it, a corpus of 13,188 entries, and 10 hours 43 minutes on a single machine. The input is fully deterministic and needs no network. Severity is rated Medium — a reliable denial of service, not memory corruption or code execution.
The tester was written with AI assistance
Clavijo announced the result on Hacker News under the title "We found a division by zero bug in FFmpeg with a vibecoded fuzzer", a thread that passed 250 points. According to the dev.to write-up, much of the ensuing debate centred on what AI-written testing tools do to the economics of bug hunting.
The tool, published on GitHub as fuzzer-tool, is described as a coverage-guided binary fuzzer with 147 mutation operators across 9 categories, 14 scheduler modules arbitrated by an Elo rating, AFL-style forkserver execution, shared-memory edge coverage, and comparison tracing down to individual call sites. Its README is candid about limits: raw throughput lags the AFL family, and AFL is recommended for production fuzzing at scale.
Nor was this a one-off. The same repo records a second FFmpeg finding, rated HIGH: a 46-byte input that reaches an av_assert0(0) in libavcodec/decode.c through the subtitle decoder path. Both arrived within a week of fuzzing on a library that Google's OSS-Fuzz has hammered continuously for years — an obscure demuxer reached through a custom I/O path is exactly the territory generic harnesses tend to miss.
The fix is two lines
The suggested patch guards nb_channels <= 0 at the top of vpk_read_packet and returns AVERROR_INVALIDDATA, with a regression test attached. The wince-inducing detail: a nearly identical guard for this exact division was proposed on the ffmpeg-devel mailing list in November 2024, but per the dev.to account it never landed on the path that mattered. The bug class was known; the fix simply did not arrive.
Reproduction depends on the I/O path
The dev.to author tried to reproduce the crash with FFmpeg 6.1.1 on Ubuntu, feeding the 21 bytes from the issue's hex dump through the command line. It did not crash. FFmpeg correctly detected the VPK container, reported an absurd audio stream with a 942,683,702 Hz sample rate and 80 channels, failed to open the ADPCM decoder, and exited cleanly with a demuxing error.
That is not a contradiction, and it is the most instructive part of the story. The trigger requires probe-time and packet-read-time data to diverge, which happens under the fuzzer's custom in-memory AVIO path; the CLI's disk-backed I/O reads a consistent snapshot. The failed reproduction is itself evidence for the root cause: the parsed channel count depends on which view of the data wins. The practical consequence is that exposure varies by application. Software that pipes untrusted bytes into FFmpeg through custom I/O callbacks is in the risk group; a plain CLI invocation is not. Even on the safe path, a parser cheerfully reporting a 942 MHz sample rate and 80 channels from 21 bytes says something about malformed-input tolerance in its own right.
Why it matters
FFmpeg is embedded in transcoders, thumbnail generators, media servers, and chat applications that routinely process untrusted uploads. A deterministic 21-byte crash is cheap to plant wherever the conditions apply, and media pipelines rarely treat demuxer input as hostile.
The deeper signal is economic. One researcher, one machine, and roughly eleven hours surfaced two real crashes in one of the most-fuzzed C codebases in existence, using a tester largely written by AI. The dev.to author argues the deciding factor was not the generated code but human-imposed discipline: convention files for the agents, templated crash reports with backtraces, and honest severity calls separating a DoS primitive from memory corruption. And the November 2024 mailing-list thread supplies the other half of the lesson: identifying a bug, or even proposing its fix, counts for nothing until the patch actually lands.
- #ffmpeg
- #security
- #fuzzing
- #open-source
- #ai