← All libraries
Codec · C
How to fuzz libopus
Opus blends two codecs in one bitstream — SILK and CELT have separate bug surfaces.
The Opus codec switches between SILK (speech) and CELT (audio) modes and interpolates between them, creating a complex state machine. CELT's band energy quantisation and its range coder must handle every combination of configuration bits — a crash in libopus affects WebRTC, Discord, Zoom, and most real-time communication stacks.
Common bug classes
- •Heap buffer overflow in CELT band energy normalisation
- •Integer overflow in range-coder renormalisation loop
- •Out-of-bounds read in SILK LPC synthesis filter
- •Divide-by-zero in pitch estimator autocorrelation
- •Assertion failure on malformed table-of-contents byte
Recommended setup
Fuzzers
- → AFL++
- → libFuzzer
- → Honggfuzz
Sanitizers
- → ASan
- → UBSan
Harness scaffold
#include <stdint.h>
#include <stddef.h>
#include <stdlib.h>
#include <opus.h>
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
int err;
OpusDecoder *dec = opus_decoder_create(48000, 2, &err);
if (!dec) return 0;
const int MAX_FRAME = 5760; /* 120 ms at 48 kHz */
opus_int16 *pcm = malloc(MAX_FRAME * 2 * sizeof(opus_int16));
if (pcm) {
opus_decode(dec, data, (opus_int32)size, pcm, MAX_FRAME, 0);
free(pcm);
}
opus_decoder_destroy(dec);
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-2017-0381
Push the harness above + a Dockerfile. First month 50% off.