From 5553a5bd0d9cb8556af1a345a399d65e97cef44c Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 18 Oct 2023 01:39:16 +0200 Subject: [PATCH] avformat/mxfdec: Check klv offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: Assertion klv_offset >= mxf->run_in failed at libavformat/mxfdec.c:736 Fixes: 62936/clusterfuzz-testcase-minimized-ffmpeg_dem_MXF_fuzzer-5778404366221312.fuzz Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Reviewed-by: Tomas Härdin Signed-off-by: Michael Niedermayer (cherry picked from commit 70f5fa63258f548cd8d067d479658bae61711ff4) Signed-off-by: Michael Niedermayer --- libavformat/mxfdec.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 32c2464fb1..ce16c4becb 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -420,12 +420,15 @@ static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size) return i == size; } -static int klv_read_packet(KLVPacket *klv, AVIOContext *pb) +static int klv_read_packet(MXFContext *mxf, KLVPacket *klv, AVIOContext *pb) { int64_t length, pos; if (!mxf_read_sync(pb, mxf_klv_key, 4)) return AVERROR_INVALIDDATA; klv->offset = avio_tell(pb) - 4; + if (klv->offset < mxf->run_in) + return AVERROR_INVALIDDATA; + memcpy(klv->key, mxf_klv_key, 4); avio_read(pb, klv->key + 4, 12); length = klv_decode_ber_length(pb); @@ -3049,7 +3052,7 @@ static int mxf_seek_to_previous_partition(MXFContext *mxf) /* Make sure this is actually a PartitionPack, and if so parse it. * See deadlock2.mxf */ - if ((ret = klv_read_packet(&klv, pb)) < 0) { + if ((ret = klv_read_packet(mxf, &klv, pb)) < 0) { av_log(mxf->fc, AV_LOG_ERROR, "failed to read PartitionPack KLV\n"); return ret; } @@ -3331,7 +3334,7 @@ static void mxf_read_random_index_pack(AVFormatContext *s) if (length < min_rip_length || length > max_rip_length) goto end; avio_seek(s->pb, file_size - length, SEEK_SET); - if (klv_read_packet(&klv, s->pb) < 0 || + if (klv_read_packet(mxf, &klv, s->pb) < 0 || !IS_KLV_KEY(klv.key, ff_mxf_random_index_pack_key)) goto end; if (klv.next_klv != file_size || klv.length <= 4 || (klv.length - 4) % 12) { @@ -3379,7 +3382,7 @@ static int mxf_read_header(AVFormatContext *s) while (!avio_feof(s->pb)) { const MXFMetadataReadTableEntry *metadata; - if (klv_read_packet(&klv, s->pb) < 0) { + if (klv_read_packet(mxf, &klv, s->pb) < 0) { /* EOF - seek to previous partition or stop */ if(mxf_parse_handle_partition_or_eof(mxf) <= 0) break; @@ -3635,7 +3638,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) if (pos < mxf->current_klv_data.next_klv - mxf->current_klv_data.length || pos >= mxf->current_klv_data.next_klv) { mxf->current_klv_data = (KLVPacket){{0}}; - ret = klv_read_packet(&klv, s->pb); + ret = klv_read_packet(mxf, &klv, s->pb); if (ret < 0) break; max_data_size = klv.length;