← All libraries
Codec · C
How to fuzz FFmpeg
The universal media Swiss-army knife — every container format is an attack surface.
FFmpeg's demuxer and decoder count is unmatched; virtually every media format on the internet passes through it. Its C codebase mixes performance-optimised SIMD with hand-crafted bitstream readers that are prime territory for bounds errors, and it is embedded in countless applications from browsers to broadcast infrastructure.
Common bug classes
- •Heap buffer overflow in bitstream reader lookahead
- •Use-after-free in AVPacket/AVFrame reference counting
- •Integer overflow in container sample/duration arithmetic
- •Out-of-bounds write in motion vector table decoding
- •Null dereference on missing mandatory container fields
Recommended setup
Fuzzers
- → AFL++
- → libFuzzer
- → Honggfuzz
Sanitizers
- → ASan
- → UBSan
Harness scaffold
#include <stdint.h>
#include <stddef.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
AVFormatContext *fmt_ctx = NULL;
AVIOContext *avio_ctx = NULL;
uint8_t *buf = av_malloc(size);
if (!buf) return 0;
memcpy(buf, data, size);
avio_ctx = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
if (!avio_ctx) { av_free(buf); return 0; }
fmt_ctx = avformat_alloc_context();
fmt_ctx->pb = avio_ctx;
if (avformat_open_input(&fmt_ctx, NULL, NULL, NULL) == 0) {
avformat_find_stream_info(fmt_ctx, NULL);
avformat_close_input(&fmt_ctx);
} else {
avformat_free_context(fmt_ctx);
av_free(avio_ctx->buffer);
avio_context_free(&avio_ctx);
}
return 0;
}Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.
Notable CVEs found by fuzzing
- → CVE-2022-3964
- → CVE-2023-49502
Push the harness above + a Dockerfile. First month 50% off.