Skip to main content
← All libraries
Codec · C

How to fuzz LAME (libmp3lame)

Decades of MP3 encoder tuning leave corner cases in psychoacoustic model arithmetic.

LAME's psychoacoustic model computes masking thresholds using floating-point arithmetic tied closely to buffer-sized arrays. Its Huffman big-value and count1 partition encoding can write past buffer ends with certain PCM amplitude distributions, and its reservoir management for variable bitrate is stateful and hard to unit-test exhaustively.

Common bug classes

  • Heap buffer overflow in Huffman big-value region encoding
  • Integer overflow in MP3 frame header bit-reservoir arithmetic
  • Out-of-bounds write in psychoacoustic spreading function
  • Divide-by-zero in ATH computation for extreme sample rates
  • Stack overflow in recursive bitrate search under VBR

Recommended setup

Fuzzers

  • AFL++
  • libFuzzer

Sanitizers

  • ASan
  • UBSan

Harness scaffold

#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <lame/lame.h>

int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
  if (size < 2) return 0;
  lame_t lame = lame_init();
  if (!lame) return 0;
  lame_set_num_channels(lame, 1);
  lame_set_in_samplerate(lame, 44100);
  lame_set_brate(lame, 128);
  lame_set_quality(lame, 9);
  if (lame_init_params(lame) < 0) { lame_close(lame); return 0; }
  int nsamples = (int)(size / 2);
  unsigned char *mp3buf = malloc(nsamples + 7200);
  if (mp3buf) {
    lame_encode_buffer(lame, (const short *)data, NULL,
                       nsamples, mp3buf, nsamples + 7200);
    free(mp3buf);
  }
  lame_close(lame);
  return 0;
}

Save this as fuzz_target.cc, build with your compiler + sanitizer flags, and you have a working starting point.

Start fuzzing LAME (libmp3lame) on Fuzze.rs →

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