From e7839602f469eb9dd5e1341d780c0c1667ac89ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomas=20H=C3=A4rdin?= Date: Wed, 21 Dec 2011 10:49:27 +0100 Subject: [PATCH] mxfdec: Never seek back in local sets and KLVs Specially crafted files can lead the parsing code to take too long. We fix a lot of these problems by not allowing local tags to extend past the end of the set and not allowing other KLVs to be read past the end of themselves. --- libavformat/mxfdec.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 5035a2fc2b..e1363747a9 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1464,6 +1464,13 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF else if (read_child(ctx, pb, tag, size, uid, -1) < 0) return -1; + /* accept the 64k local set limit being exceeded (Avid) + * don't accept it extending past the end of the KLV though (zzuf5.mxf) */ + if (avio_tell(pb) > klv_end) { + av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x extends past end of local set @ %#"PRIx64"\n", + tag, klv->offset); + return AVERROR_INVALIDDATA; + } else if (avio_tell(pb) <= next) /* only seek forward, else this can loop for a long time */ avio_seek(pb, next, SEEK_SET); } if (ctx_size) ctx->type = type; @@ -1667,6 +1674,14 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) } else { uint64_t next = avio_tell(s->pb) + klv.length; res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset); + + /* only seek forward, else this can loop for a long time */ + if (avio_tell(s->pb) > next) { + av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n", + klv.offset); + return AVERROR_INVALIDDATA; + } + avio_seek(s->pb, next, SEEK_SET); } if (res < 0) {