Skip to main content
← 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
Start fuzzing FFmpeg on Fuzze.rs →

Push the harness above + a Dockerfile. First month 50% off.