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);