[CVE patch] CVE patch in libav version 11.7 98/76098/3 accepted/tizen/common/20160623.154053 accepted/tizen/ivi/20160623.123157 accepted/tizen/mobile/20160623.123103 accepted/tizen/tv/20160623.123121 accepted/tizen/wearable/20160623.123140 submit/tizen/20160622.235044
authorJiyong Min <jiyong.min@samsung.com>
Wed, 22 Jun 2016 23:29:31 +0000 (08:29 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Wed, 22 Jun 2016 23:38:17 +0000 (08:38 +0900)
 - asfenc: fix some possible integer overflows (CVE-2016-2326)
 - mov: Check the entries value when parsing dref boxes (CVE-2016-3062)

Change-Id: I4a21091a20e10ee4b68f27ee4f5f5df6e419eca3
Signed-off-by: Jiyong Min <jiyong.min@samsung.com>
libavformat/asfenc.c
libavformat/mov.c

index 79b44a7..4ae52bd 100644 (file)
@@ -191,7 +191,7 @@ typedef struct {
     ASFStream streams[128];              ///< it's max number and it's not that big
     /* non streamed additonnal info */
     uint64_t nb_packets;                 ///< how many packets are there in the file, invalid if broadcasting
-    int64_t duration;                    ///< in 100ns units
+    uint64_t duration;                    ///< in 100ns units
     /* packet filling */
     unsigned char multi_payloads_present;
     int packet_size_left;
@@ -359,7 +359,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
     AVCodecContext *enc;
     int64_t header_offset, cur_pos, hpos;
     int bit_rate;
-    int64_t duration;
+    uint64_t play_duration, send_duration;
 
     ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL);
 
@@ -369,7 +369,16 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
     tags[3] = av_dict_get(s->metadata, "comment", NULL, 0);
     tags[4] = av_dict_get(s->metadata, "rating", NULL, 0);
 
-    duration       = asf->duration + PREROLL_TIME * 10000;
+    if (asf->duration > UINT64_MAX / 10000 - PREROLL_TIME) {
+        av_log(s, AV_LOG_WARNING, "Duration %"PRIu64" too large\n", asf->duration);
+        if (s->error_recognition & AV_EF_EXPLODE)
+            return AVERROR(ERANGE);
+        send_duration = 0;
+        play_duration = 0;
+    } else {
+        send_duration  = asf->duration * 10000;
+        play_duration  = (asf->duration + PREROLL_TIME) * 10000;
+    }
     has_title      = tags[0] || tags[1] || tags[2] || tags[3] || tags[4];
     metadata_count = av_dict_count(s->metadata);
 
@@ -400,8 +409,8 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size,
     file_time = 0;
     avio_wl64(pb, unix_to_file_time(file_time));
     avio_wl64(pb, asf->nb_packets); /* number of packets */
-    avio_wl64(pb, duration); /* end time stamp (in 100ns units) */
-    avio_wl64(pb, asf->duration); /* duration (in 100ns units) */
+    avio_wl64(pb, play_duration); /* end time stamp (in 100ns units) */
+    avio_wl64(pb, send->duration); /* duration (in 100ns units) */
     avio_wl64(pb, PREROLL_TIME); /* start time stamp */
     avio_wl32(pb, (asf->is_streamed || !pb->seekable) ? 3 : 2);  /* ??? */
     avio_wl32(pb, s->packet_size); /* packet size */
@@ -832,7 +841,6 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
     ASFContext *asf = s->priv_data;
     AVIOContext *pb = s->pb;
     ASFStream *stream;
-    int64_t duration;
     AVCodecContext *codec;
     int64_t packet_st, pts;
     int start_sec, i;
@@ -847,8 +855,9 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts;
     assert(pts != AV_NOPTS_VALUE);
-    duration      = pts * 10000;
-    asf->duration = FFMAX(asf->duration, duration + pkt->duration * 10000);
+    if (pts > UINT64_MAX - pkt->duration)
+        return AVERROR(ERANGE);
+    asf->duration = FFMAX(asf->duration, pts + pkt->duration);
 
     packet_st = asf->nb_packets;
     put_frame(s, stream, s->streams[pkt->stream_index],
@@ -856,8 +865,15 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
 
     /* check index */
     if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) {
-        start_sec = (int)(duration / INT64_C(10000000));
-        if (start_sec != (int)(asf->last_indexed_pts / INT64_C(10000000))) {
+        if (pts / 1000LL > INT_MAX)
+            return AVERROR(ERANGE);
+
+        start_sec = pts / 1000;
+        if (start_sec != asf->last_indexed_pts / 1000) {        if (pts / 1000LL > INT_MAX)
+            return AVERROR(ERANGE);
+
+        start_sec = pts / 1000;
+        if (start_sec != asf->last_indexed_pts / 1000) {
             for (i = asf->nb_index_count; i < start_sec; i++) {
                 if (i >= asf->nb_index_memory_alloc) {
                     int err;
@@ -878,7 +894,7 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt)
                                                         (uint16_t)(asf->nb_packets - packet_st));
             }
             asf->nb_index_count   = start_sec;
-            asf->last_indexed_pts = duration;
+            asf->last_indexed_pts = pts;
         }
     }
     return 0;
index 2c6ebb1..35105a8 100755 (executable)
@@ -412,9 +412,11 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 
     avio_rb32(pb); // version + flags
     entries = avio_rb32(pb);
-    if (entries >  (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
+    if (!entries ||
+       entries >  (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
         entries >= UINT_MAX / sizeof(*sc->drefs))
         return AVERROR_INVALIDDATA;
+    sc->drefs_count = 0;
     av_free(sc->drefs);
     sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
     if (!sc->drefs)