{"slug": "21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of", "title": "21 Bytes Can Crash FFmpeg: Inside the Vibecoded Fuzzer That Found What Years of Audits Missed", "summary": "Darío Clavijo used an AI-assisted, 'vibecoded' fuzzer to discover a division-by-zero vulnerability in FFmpeg's VPK demuxer, triggered by a 21-byte file, and a second high-severity bug in the subtitle decoder path. The findings, posted on Hacker News, highlight how AI-generated fuzzing tools can uncover bugs in heavily audited codebases.", "body_md": "Twenty-one bytes. That is the entire attack. A file smaller than a URL, with four zero bytes sitting at exactly the right offset, crashes any FFmpeg-based application that opens it and reads a packet. Not memory corruption, not some exotic heap trick. A division by zero, in code that has been shipping for years, in one of the most fuzzed codebases on the planet.\n\nThe person who found it, Darío Clavijo, did not write the fuzzer by hand. He built it with AI assistance, the way a growing number of security researchers now work, and posted the result on Hacker News this week under a title that got my attention immediately: \"We found a division by zero bug in FFmpeg with a vibecoded fuzzer.\" The thread climbed past 250 points with hundreds of comments, and the debate underneath it is the real story: AI has been writing application code for two years, but AI writing the *tester* changes the economics of finding bugs in ways most teams have not priced in yet.\n\nFull disclosure before I go further. I am not a C security researcher. I run my own AI agent infrastructure and I write Java for a living. What I did for this article is what I would want you to do: I cloned the fuzzer's public repo, read its findings documents, tried to reproduce the crash on my own Ubuntu box, and studied the harness code line by line. Everything below is sourced from the public FFmpeg issue, the repo, and my own experiment, with the one place my results diverged clearly marked.\n\nThe bug lives in `libavformat/vpk.c`\n\n, the demuxer for Sony PS2 VPK audio files, a container format almost nobody has heard of. That obscurity is exactly the point. In [issue #24290 on the FFmpeg tracker](https://code.ffmpeg.org/FFmpeg/FFmpeg/issues/24290), the crash chain reads like this:\n\n`VPK`\n\nmagic bytes and assigns the VPK demuxer.`vpk_read_header`\n\nreads a 24-byte header. The crafted input sets the channel count, `nb_channels`\n\n, to zero at bytes 14 through 17. The header code does validate that the channel count is positive, but in the fuzzer's custom-I/O setup the data seen during probing and the data seen during packet reading can diverge.`vpk_read_packet`\n\nhandles the final audio block, `nb_channels`\n\nis back to zero, and line 89 divides `last_block_size`\n\nby it. The CPU raises SIGFPE and the process dies.The issue's crash metadata is what makes this credible rather than anecdotal:\n\nThe suggested fix is two lines: guard `nb_channels <= 0`\n\nat the top of `vpk_read_packet`\n\nand return `AVERROR_INVALIDDATA`\n\n. A regression test ships alongside it. There is even a detail that made me wince: a nearly identical guard for this exact division was proposed on the ffmpeg-devel mailing list back in November 2024. The bug class was known. The guard apparently never landed on the path that mattered.\n\nAnd this was not a lucky one-off. The same repo documents a second FFmpeg finding, rated HIGH: a 46-byte input that reaches a reachable `av_assert0(0)`\n\nin `libavcodec/decode.c`\n\nthrough the subtitle decoder path. Two real crashes in one week of fuzzing, in a library that Google's OSS-Fuzz has hammered continuously for years.\n\nThe word \"vibecoded\" in the title does a lot of work, and I think it misleads people in an interesting way. Reading the reactions, a chunk of commenters clearly assumed this meant someone prompted an AI for a weekend, got a sloppy script, and got lucky. The repo tells a different story.\n\nThe fuzzer, [published on GitHub as fuzzer-tool](https://github.com/daedalus/fuzzer/), describes itself as a coverage-guided binary fuzzer with 147 mutation operators across 9 categories, 14 scheduler modules under Elo arbitration, AFL-style forkserver execution, shared-memory edge coverage, and comparison tracing down to individual call sites. The README even carries an honest caveat that most AI-generated tooling lacks: it admits the tool is slower in raw throughput than the AFL family and says that for production fuzzing at scale, AFL remains the better choice.\n\nWhen I cloned the repo, the file that convinced me this is engineering rather than luck was `AGENTS.md`\n\n, the instruction file the human maintains for the AI agents that work on the codebase. It contains rules like: always find the closest existing example and match its conventions before adding anything, never bypass pre-commit hooks, register new mutation operators in a single source-of-truth registry so every scheduler discovers them automatically, and never commit corpus directories. The findings documents follow a template with crash metadata, GDB backtraces, an exploitability assessment separating \"this is a DoS primitive\" from \"this is memory corruption,\" a suggested fix, and a regression test.\n\nThat last part is the actual lesson. The AI wrote a lot of the code. The *discipline* around it, the conventions, the triage rigor, the honest severity assessment, is human-imposed structure. Vibecoding with guardrails produces this. Vibecoding without them produces the pile of insecure repositories we have all been reading about instead.\n\nI saved the 21 bytes from the issue's hex dump to a file and ran my system's FFmpeg against it, version 6.1.1 on Ubuntu:\n\n```\nprintf '\\x20\\x4b\\x50\\x56\\x56\\x50\\x00\\xf8\\x04\\x00\\x3b\\x03\\x61\\x39\\x56\\x32\\x36\\x36\\x30\\x38\\x50' > vpk_crash.bin\nffmpeg -i vpk_crash.bin -c:a copy -f null -\n```\n\nMy result: no crash. FFmpeg correctly detected the file as a 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. Which is exactly the behavior you would want.\n\nThis is not a contradiction, and understanding why is the most instructive part of the whole story. The issue's trigger chain is specific: the crash requires the probe-time data and the packet-read-time data to diverge, which happens in the fuzzer's custom AVIO path, where the harness feeds FFmpeg from an in-memory buffer it controls. The CLI reading a file from disk takes a different path through the I/O layer. My mismatch is itself evidence for the bug's root cause: the channel count genuinely depends on which snapshot of the data you ask, and that ambiguity is what kills the dividing instruction when the wrong snapshot wins.\n\nTwo takeaways from my failed-and-then-understood reproduction:\n\nThe fuzzer's FFmpeg target, `ffmpeg_read.c`\n\n, is a masterclass in what a fuzz harness should be, and none of it is complicated once you see the shape. The core loop is five FFmpeg API calls:\n\n```\navformat_open_input(&fmt_ctx, NULL, NULL, NULL);\navformat_find_stream_info(fmt_ctx, NULL);\nwhile (av_read_frame(fmt_ctx, pkt) >= 0) {\n    avcodec_send_packet(dec_ctx, pkt);\n    while (avcodec_receive_frame(dec_ctx, frame) >= 0) { /* got frames */ }\n}\navformat_close_input(&fmt_ctx);\n```\n\nAround that skeleton sit the details that separate a toy from a bug finder:\n\n`AVIOContext`\n\nbacked by a memory buffer, so each mutated input is fed at memory speed and, crucially, through the custom-I/O path where probe and packet data can diverge. That is precisely where the VPK bug lived.`-fsanitize=address`\n\n. Memory bugs that would silently corrupt data on a normal build become loud, attributed crashes on an instrumented one.If you want to do this against your own parser, whether it is C, a file-format library, or an HTTP header parser in any language, the recipe is the same five steps:\n\nHere is the number that keeps turning over in my head: 10 hours and 43 minutes. One machine, one overnight run, and out pops a deterministic crash in FFmpeg, a library that has been fuzzed continuously by OSS-Fuzz for the better part of a decade, with a fix suggested and a regression test written. The marginal cost of finding a real, reportable bug in critical infrastructure just dropped to \"leave your laptop running while you sleep.\"\n\nFor defenders, the implication is uncomfortable but simple. The surface area of AI-assisted fuzzing is now everyone's production dependency tree, and the bug classes that fall first are the unglamorous ones, the rarely-touched demuxers and obscure format branches where a validation guard has been missing for years. Anything that parses attacker-controlled bytes needs a fuzzing story, and \"nobody will bother\" is no longer an excuse, because bothering now costs pennies of compute.\n\nFor builders, the implication is the opposite of the doom reading. The same economics that weaponize the fuzzer are available to your team this week. An AI-assisted fuzzer aimed at your own parser before your next release is one of the highest-leverage hours you can spend, and the repo we walked through is a free blueprint for doing it with discipline instead of vibes.\n\nThe HN debate about whether AI-generated tooling \"counts\" as security research will keep running. Meanwhile the issues get filed, the two-line guards land or do not, and the people who learned to build the testers are quietly finding things the audits missed.\n\nI write about AI, developer tools, and the engineering behind them every week. Subscribe, it is free, and it tells me which deep dives are worth doing next.\n\nHave you pointed a fuzzer at your own code, vibecoded or otherwise? What did it find, and what stopped you from triaging the results? I read every reply.", "url": "https://wpnews.pro/news/21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of", "canonical_source": "https://dev.to/jamilxt/21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of-audits-missed-fpe", "published_at": "2026-08-29 03:10:59+00:00", "updated_at": "2026-08-29 03:48:44.934340+00:00", "lang": "en", "topics": ["artificial-intelligence", "developer-tools", "ai-tools"], "entities": ["Darío Clavijo", "FFmpeg", "Hacker News", "Google OSS-Fuzz", "GitHub"], "alternates": {"html": "https://wpnews.pro/news/21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of", "markdown": "https://wpnews.pro/news/21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of.md", "text": "https://wpnews.pro/news/21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of.txt", "jsonld": "https://wpnews.pro/news/21-bytes-can-crash-ffmpeg-inside-the-vibecoded-fuzzer-that-found-what-years-of.jsonld"}}