aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat/mxfdec.c
diff options
context:
space:
mode:
authorMichael Niedermayer <michaelni@gmx.at>2011-12-22 14:04:42 +0100
committerMichael Niedermayer <michaelni@gmx.at>2011-12-22 14:04:49 +0100
commitdd1fb6528791b32ac9d6b3c2d81707cf1949ec5d (patch)
treea36e7a71cb40b860ac8014119d5f2541d50db243 /libavformat/mxfdec.c
parent834f80db22c186f3d0662754f6a00085c64c2323 (diff)
parentcc1dda851b082826e652d698a9ca4738fc2a0ea5 (diff)
downloadffmpeg-dd1fb6528791b32ac9d6b3c2d81707cf1949ec5d.tar.gz
Merge remote-tracking branch 'tjoppen/fuzz_fixes'
* tjoppen/fuzz_fixes: mxfdec: Don't crash in mxf_packet_timestamps() if current_edit_unit overflows mxfdec: Zero nb_ptses in mxf_compute_ptses_fake_index() mxfdec: Sanity check PreviousPartition mxfdec: Never seek back in local sets and KLVs mxfdec: Move the current_partition check inside mxf_read_header() mxfdec: Fix infinite loop in mxf_packet_timestamps() mxfdec: Check url_feof() in mxf_read_local_tags() mxfdec: Check for NULL component Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/mxfdec.c')
-rw-r--r--libavformat/mxfdec.c55
1 files changed, 44 insertions, 11 deletions
diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c
index b6a63c90a2..47fa81d495 100644
--- a/libavformat/mxfdec.c
+++ b/libavformat/mxfdec.c
@@ -479,6 +479,13 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size
partition->previous_partition, footer_partition,
partition->index_sid, partition->body_sid);
+ /* sanity check PreviousPartition if set */
+ if (partition->previous_partition &&
+ mxf->run_in + partition->previous_partition >= klv_offset) {
+ av_log(mxf->fc, AV_LOG_ERROR, "PreviousPartition points to this partition or forward\n");
+ return AVERROR_INVALIDDATA;
+ }
+
if (op[12] == 1 && op[13] == 1) mxf->op = OP1a;
else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b;
else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c;
@@ -1021,8 +1028,10 @@ static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_ta
for (i = 0; i < index_table->nb_segments; i++) {
MXFIndexTableSegment *s = index_table->segments[i];
- if (!s->nb_index_entries)
+ if (!s->nb_index_entries) {
+ index_table->nb_ptses = 0;
return 0; /* no TemporalOffsets */
+ }
index_table->nb_ptses += s->index_duration;
}
@@ -1276,7 +1285,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf)
break;
}
}
- if (!source_track)
+ if (!source_track || !component)
continue;
if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) {
@@ -1437,7 +1446,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF
if (!ctx)
return -1;
- while (avio_tell(pb) + 4 < klv_end) {
+ while (avio_tell(pb) + 4 < klv_end && !url_feof(pb)) {
int tag = avio_rb16(pb);
int size = avio_rb16(pb); /* KLV specified by 0x53 */
uint64_t next = avio_tell(pb) + size;
@@ -1464,6 +1473,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;
@@ -1500,11 +1516,6 @@ static int mxf_parse_handle_essence(MXFContext *mxf)
AVIOContext *pb = mxf->fc->pb;
int64_t ret;
- if (!mxf->current_partition) {
- av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to PartitionPack\n");
- return AVERROR_INVALIDDATA;
- }
-
if (mxf->parsing_backward) {
return mxf_seek_to_previous_partition(mxf);
} else {
@@ -1620,6 +1631,12 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
IS_KLV_KEY(klv.key, mxf_essence_element_key) ||
IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) ||
IS_KLV_KEY(klv.key, mxf_system_item_key)) {
+
+ if (!mxf->current_partition) {
+ av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to first PartitionPack\n");
+ return AVERROR_INVALIDDATA;
+ }
+
if (!mxf->current_partition->essence_offset) {
/* for OP1a we compute essence_offset
* for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25)
@@ -1666,6 +1683,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) {
@@ -1712,7 +1737,7 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap)
*/
static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt)
{
- int64_t next_ofs;
+ int64_t last_ofs = -1, next_ofs;
MXFIndexTable *t = &mxf->index_tables[0];
/* this is called from the OP1a demuxing logic, which means there may be no index tables */
@@ -1720,17 +1745,25 @@ static void mxf_packet_timestamps(MXFContext *mxf, AVPacket *pkt)
return;
/* find mxf->current_edit_unit so that the next edit unit starts ahead of pkt->pos */
- for (;;) {
+ while (mxf->current_edit_unit >= 0) {
if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0)
break;
+ if (next_ofs <= last_ofs) {
+ /* large next_ofs didn't change or current_edit_unit wrapped around
+ * this fixes the infinite loop on zzuf3.mxf */
+ av_log(mxf->fc, AV_LOG_ERROR, "next_ofs didn't change. not deriving packet timestamps\n");
+ return;
+ }
+
if (next_ofs > pkt->pos)
break;
+ last_ofs = next_ofs;
mxf->current_edit_unit++;
}
- if (mxf->current_edit_unit >= t->nb_ptses)
+ if (mxf->current_edit_unit < 0 || mxf->current_edit_unit >= t->nb_ptses)
return;
pkt->dts = mxf->current_edit_unit + t->first_dts;