On 7/3/2022 7:00 AM, Nicolas George wrote:
Andreas Rheinhardt (12022-07-03):
if (!av_bprint_is_complete(bp))
- return AVERROR(ENOMEM);
+ break;
Isn't this actually still against the API? av_channel_layout_describe()
will not return the correct number of bytes necessary to write the
string for the channel layout.
You are both right.
BPrint-based APIs are not supposed to check for truncation, because
printing into a bounded buffer to determine the necessary size is a
valid use (see AV_BPRINT_SIZE_COUNT_ONLY).
What is wrong is Michael's original fix:
commit 8154cb7c2ff2afcb1a0842de8c215b7714c814d0
Author: Michael Niedermayer <mich...@niedermayer.cc>
Date: 2022-06-30 00:00:32 +0200
avutil/channel_layout: av_channel_layout_describe_bprint: Check for buffer
end
Fixes: Timeout printing a billion channels
Fixes:
48099/clusterfuzz-testcase-minimized-ffmpeg_dem_MATROSKA_fuzzer-6754782204788736
Found-by: continuous fuzzing process
https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <mich...@niedermayer.cc>
diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c
index 21b70173b7..1887987789 100644
--- a/libavutil/channel_layout.c
+++ b/libavutil/channel_layout.c
@@ -757,6 +757,10 @@ int av_channel_layout_describe_bprint(const
AVChannelLayout *channel_layout,
if (channel_layout->order == AV_CHANNEL_ORDER_CUSTOM &&
channel_layout->u.map[i].name[0])
If the channel count is insanely high, then this will cause invalid
reads.
av_bprintf(bp, "@%s", channel_layout->u.map[i].name);
+
+ if (!av_bprint_is_complete(bp))
+ return AVERROR(ENOMEM);
+
}
if (channel_layout->nb_channels) {
av_bprintf(bp, ")");
Obviously, this fuzzer found a case where a demuxer or a decoder
constructs an invalid channel layout in memory without proper
validation. There is a bug, possibly an security-related one, and this
only hides it from the test suite.
The Matroska demuxer could in theory generate a native layout with more
than 64 channels where popcnt(mask) != channels, and nothing seems to
validate what a demuxer's read_header() callback returns if you just
call lavf API functions like target_dem_fuzzer.c seems to do.
Maybe:
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 73ded761fd..ad7ee390a2 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -2950,10 +2950,10 @@ static int matroska_parse_tracks(AVFormatContext *s)
st->codecpar->codec_tag = fourcc;
st->codecpar->sample_rate = track->audio.out_samplerate;
// channel layout may be already set by codec private checks above
- if (st->codecpar->ch_layout.order == AV_CHANNEL_ORDER_NATIVE &&
- !st->codecpar->ch_layout.u.mask)
+ if (!av_channel_layout_check(&st->codecpar->ch_layout)) {
st->codecpar->ch_layout.order = AV_CHANNEL_ORDER_UNSPEC;
- st->codecpar->ch_layout.nb_channels = track->audio.channels;
+ st->codecpar->ch_layout.nb_channels = track->audio.channels;
+ }
if (!st->codecpar->bits_per_coded_sample)
st->codecpar->bits_per_coded_sample = track->audio.bitdepth;
if (st->codecpar->codec_id == AV_CODEC_ID_MP3 ||
is enough to ensure a valid layout is propagated. This assumes
parameters set by codec private parsing are correct (only FLAC seem to
be present right now, and it is).
Assuming i got this right, in this fuzzing sample's case it would still
have a billion channels (since that's what track->audio.channels
contains, as read from the container), but using the unspec layout,
which is technically valid even if nothing will really handle it, and
av_channel_layout_describe() will print a small string.
Still, i think a check in avformat_open_input() might also be a good
idea, especially once (and if) demuxers start propagating custom
layouts, where the map array will be allocated.
The proper fix is to find where the input is improperly validated, and
then revert this change.
I do not know how to exploit the
"48099/clusterfuzz-testcase-minimized-ffmpeg_dem_MATROSKA_fuzzer-6754782204788736"
information to reproduce the bug and investigate.
Michael can share the sample, but you need to compile
tools/target_dem_fuzzer.c to read it.
Regards,
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".