Skip to content

audio: ffmpeg_dec: reject frames whose channel count differs from sink - #11351

Open
Shrusti-pk wants to merge 1 commit into
thesofproject:mainfrom
Shrusti-pk:ffmpeg-dec-channel-mismatch
Open

Shrusti-pk wants to merge 1 commit into
thesofproject:mainfrom
Shrusti-pk:ffmpeg-dec-channel-mismatch

Conversation

@Shrusti-pk

Copy link
Copy Markdown
Contributor

ffmpeg_dec_convert_frame() reads each decoded frame using the sink's channel count. The frame's own channel count comes from the compressed stream and is never compared with the sink's:

  • A mono FLAC/MP3 stream played into a stereo pipeline makes the interleaved paths read nb_samples * 2 samples from a buffer that holds nb_samples, so the over-read heap bytes go out to the sink as PCM.
  • The planar stereo fast paths and conv_generic() use frame->data[ch] for channels the frame does not have, which are NULL.
  • Repro: encode a mono 16-bit FLAC stream, decode it with the flac parser and decoder as ffmpeg_dec_ff_decode() does, and pass each frame to ffmpeg_dec_convert_frame() with a stereo S32 sink. Built against libavcodec n7.1 under ASan, this gives a heap-buffer-overflow READ in conv_s16_to_s32_interleaved, 0 bytes after the 9216-byte frame buffer.

The converter now returns -EINVAL on a channel mismatch before reading anything, and the decode loop already drops a frame it rejects. With the fix, output for streams whose channel count matches the sink (mono to mono, stereo to stereo, S16 and S32) is byte-identical to before. I added no in-tree test because nothing in tree builds ffmpeg_dec against libavcodec yet (TESTING.md).

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.
@sofci

sofci commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Can one of the admins verify this patch?

reply test this please to run this test once

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants