From c53f1f3290d54deaf00503cdefbfa6c76a0113b6 Mon Sep 17 00:00:00 2001 From: Shrushti P K Date: Fri, 23 Oct 2026 17:30:54 +0530 Subject: [PATCH] audio: ffmpeg_dec: reject frames whose channel count differs from sink ffmpeg_dec_convert_frame() interleaves a decoded AVFrame using the sink channel count, but the frame's own channel count comes from the compressed bitstream and is never compared with it. When the stream has fewer channels than the sink, e.g. a mono FLAC or MP3 played into a stereo pipeline, every conversion path reads past the decoded frame: the interleaved copies read nb_samples * sink_channels samples from a buffer holding nb_samples * stream_channels, and the planar paths use frame->data[ch] for channels the frame does not have. With a 4608-sample mono FLAC frame and a stereo S32 sink this is a 9216 byte heap over-read past the frame buffer, and the bytes read are written to the sink as PCM. Return -EINVAL when frame->ch_layout.nb_channels does not match the sink. The decode loop already drops a frame the converter rejects. --- src/audio/ffmpeg_dec/ffmpeg_dec-convert.c | 8 ++++++++ src/audio/ffmpeg_dec/ffmpeg_dec-convert.h | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/audio/ffmpeg_dec/ffmpeg_dec-convert.c b/src/audio/ffmpeg_dec/ffmpeg_dec-convert.c index c9b1e9ec51e2..a499efb62a91 100644 --- a/src/audio/ffmpeg_dec/ffmpeg_dec-convert.c +++ b/src/audio/ffmpeg_dec/ffmpeg_dec-convert.c @@ -345,6 +345,14 @@ int ffmpeg_dec_convert_frame(const AVFrame *frame, uint8_t *out, size_t out_size if (channels <= 0 || frame->nb_samples <= 0) return -EINVAL; + + /* + * The frame's channel count comes from the bitstream, @channels from the + * sink. Every path below indexes the frame planes with @channels, so a + * stream with fewer channels than the sink would be read past its end. + */ + if (frame->ch_layout.nb_channels != channels) + return -EINVAL; if (need > out_size) return -ENOSPC; diff --git a/src/audio/ffmpeg_dec/ffmpeg_dec-convert.h b/src/audio/ffmpeg_dec/ffmpeg_dec-convert.h index 9ae6edc44659..9ba02adc8911 100644 --- a/src/audio/ffmpeg_dec/ffmpeg_dec-convert.h +++ b/src/audio/ffmpeg_dec/ffmpeg_dec-convert.h @@ -22,7 +22,8 @@ * Dispatches to specialized HiFi/SIMD and unrolled scalar conversion routines * based on the source AVFrame format and the destination SOF sink format. * - * Returns number of bytes written, or a negative errno on error. + * Returns number of bytes written, -ENOSPC if @out is too small, or -EINVAL for + * an empty frame or one whose channel count does not match @channels. */ int ffmpeg_dec_convert_frame(const AVFrame *frame, uint8_t *out, size_t out_size, int sink_fmt, int channels);