aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomas Härdin <tomas.hardin@codemill.se>2011-12-21 10:49:27 +0100
committerTomas Härdin <tomas.hardin@codemill.se>2011-12-21 14:17:29 +0100
commite7839602f469eb9dd5e1341d780c0c1667ac89ad (patch)
tree91158b40361b405f2cb1a3a7578f34c26733e176
parent184f479096dabcb1eafd9c661304f410a76780ed (diff)
downloadffmpeg-e7839602f469eb9dd5e1341d780c0c1667ac89ad.tar.gz
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.
-rw-r--r--libavformat/mxfdec.c15
1 files changed, 15 insertions, 0 deletions
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) {