diff options
author | Jacob Trimble <modmaker@google.com> | 2018-06-07 10:29:33 -0700 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2018-06-09 20:44:50 +0200 |
commit | cf81a9c07891966cca6d3bb31ed6931fae1f77ea (patch) | |
tree | e8812394843e14d8bd7ed64e95514eab120b3890 | |
parent | 7b80df677aa85c7d5cba457de915eac6108ec4e8 (diff) | |
download | ffmpeg-cf81a9c07891966cca6d3bb31ed6931fae1f77ea.tar.gz |
avformat/mov: Fix reading saio/saiz for clear content.
This validates that the common encryption saio/saiz atoms only appear
when the data is actually encrypted. This also ignores those atoms
in clear content.
Found by Chrome's ClusterFuzz: http://crbug.com/850389
Signed-off-by: Jacob Trimble <modmaker@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/mov.c | 71 |
1 files changed, 55 insertions, 16 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 4ad19122b3..2fca025889 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -6035,7 +6035,7 @@ static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVEncryptionIndex *encryption_index; MOVStreamContext *sc; int ret; - unsigned int sample_count; + unsigned int sample_count, aux_info_type, aux_info_param; ret = get_current_encryption_info(c, &encryption_index, &sc); if (ret != 1) @@ -6054,14 +6054,33 @@ static int mov_read_saiz(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_r8(pb); /* version */ if (avio_rb24(pb) & 0x01) { /* flags */ - if (avio_rb32(pb) != sc->cenc.default_encrypted_sample->scheme) { - av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n"); - return 0; - } - if (avio_rb32(pb) != 0) { - av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n"); - return 0; + aux_info_type = avio_rb32(pb); + aux_info_param = avio_rb32(pb); + if (sc->cenc.default_encrypted_sample) { + if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) { + av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type\n"); + return 0; + } + if (aux_info_param != 0) { + av_log(c->fc, AV_LOG_DEBUG, "Ignoring saiz box with non-zero aux_info_type_parameter\n"); + return 0; + } + } else { + // Didn't see 'schm' or 'tenc', so this isn't encrypted. + if ((aux_info_type == MKBETAG('c','e','n','c') || + aux_info_type == MKBETAG('c','e','n','s') || + aux_info_type == MKBETAG('c','b','c','1') || + aux_info_type == MKBETAG('c','b','c','s')) && + aux_info_param == 0) { + av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saiz without schm/tenc\n"); + return AVERROR_INVALIDDATA; + } else { + return 0; + } } + } else if (!sc->cenc.default_encrypted_sample) { + // Didn't see 'schm' or 'tenc', so this isn't encrypted. + return 0; } encryption_index->auxiliary_info_default_size = avio_r8(pb); @@ -6089,7 +6108,8 @@ static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVEncryptionIndex *encryption_index; MOVStreamContext *sc; int i, ret; - unsigned int version, entry_count, alloc_size = 0; + unsigned int version, entry_count, aux_info_type, aux_info_param; + unsigned int alloc_size = 0; ret = get_current_encryption_info(c, &encryption_index, &sc); if (ret != 1) @@ -6108,14 +6128,33 @@ static int mov_read_saio(MOVContext *c, AVIOContext *pb, MOVAtom atom) version = avio_r8(pb); /* version */ if (avio_rb24(pb) & 0x01) { /* flags */ - if (avio_rb32(pb) != sc->cenc.default_encrypted_sample->scheme) { - av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n"); - return 0; - } - if (avio_rb32(pb) != 0) { - av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n"); - return 0; + aux_info_type = avio_rb32(pb); + aux_info_param = avio_rb32(pb); + if (sc->cenc.default_encrypted_sample) { + if (aux_info_type != sc->cenc.default_encrypted_sample->scheme) { + av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type\n"); + return 0; + } + if (aux_info_param != 0) { + av_log(c->fc, AV_LOG_DEBUG, "Ignoring saio box with non-zero aux_info_type_parameter\n"); + return 0; + } + } else { + // Didn't see 'schm' or 'tenc', so this isn't encrypted. + if ((aux_info_type == MKBETAG('c','e','n','c') || + aux_info_type == MKBETAG('c','e','n','s') || + aux_info_type == MKBETAG('c','b','c','1') || + aux_info_type == MKBETAG('c','b','c','s')) && + aux_info_param == 0) { + av_log(c->fc, AV_LOG_ERROR, "Saw encrypted saio without schm/tenc\n"); + return AVERROR_INVALIDDATA; + } else { + return 0; + } } + } else if (!sc->cenc.default_encrypted_sample) { + // Didn't see 'schm' or 'tenc', so this isn't encrypted. + return 0; } entry_count = avio_rb32(pb); |