avformat/vividas: Test size and packet numbers a bit more
authorMichael Niedermayer <michael@niedermayer.cc>
Wed, 4 Sep 2019 14:30:00 +0000 (16:30 +0200)
committerMichael Niedermayer <michael@niedermayer.cc>
Tue, 24 Sep 2019 15:53:39 +0000 (17:53 +0200)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavformat/vividas.c

index 4cb371f5561ecefe602281300ce8be12e92ba3e9..efe1b8deffdaf14a87ab59218dd4c93e45279ddd 100644 (file)
@@ -429,6 +429,7 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu
     int maxnp=0;
     AVIOContext *pb;
     int i;
     int maxnp=0;
     AVIOContext *pb;
     int i;
+    int64_t filesize = avio_size(s->pb);
 
     pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
     if (!pb)
 
     pb = avio_alloc_context(buf, size, 0, NULL, NULL, NULL, NULL);
     if (!pb)
@@ -437,11 +438,8 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu
     ffio_read_varlen(pb); // track_index_len
     avio_r8(pb); // 'c'
     viv->n_sb_blocks = ffio_read_varlen(pb);
     ffio_read_varlen(pb); // track_index_len
     avio_r8(pb); // 'c'
     viv->n_sb_blocks = ffio_read_varlen(pb);
-    if (viv->n_sb_blocks * 2 > size) {
-        viv->n_sb_blocks = 0;
-        av_free(pb);
-        return AVERROR_INVALIDDATA;
-    }
+    if (viv->n_sb_blocks * 2 > size)
+        goto error;
     viv->sb_blocks = av_calloc(viv->n_sb_blocks, sizeof(VIV_SB_block));
     if (!viv->sb_blocks) {
         viv->n_sb_blocks = 0;
     viv->sb_blocks = av_calloc(viv->n_sb_blocks, sizeof(VIV_SB_block));
     if (!viv->sb_blocks) {
         viv->n_sb_blocks = 0;
@@ -453,24 +451,37 @@ static int track_index(VividasDemuxContext *viv, AVFormatContext *s, uint8_t *bu
     poff = 0;
 
     for (i = 0; i < viv->n_sb_blocks; i++) {
     poff = 0;
 
     for (i = 0; i < viv->n_sb_blocks; i++) {
+        uint64_t size_tmp      = ffio_read_varlen(pb);
+        uint64_t n_packets_tmp = ffio_read_varlen(pb);
+
+        if (size_tmp > INT_MAX || n_packets_tmp > INT_MAX)
+            goto error;
+
         viv->sb_blocks[i].byte_offset = off;
         viv->sb_blocks[i].packet_offset = poff;
 
         viv->sb_blocks[i].byte_offset = off;
         viv->sb_blocks[i].packet_offset = poff;
 
-        viv->sb_blocks[i].size = ffio_read_varlen(pb);
-        viv->sb_blocks[i].n_packets = ffio_read_varlen(pb);
+        viv->sb_blocks[i].size = size_tmp;
+        viv->sb_blocks[i].n_packets = n_packets_tmp;
 
         off += viv->sb_blocks[i].size;
         poff += viv->sb_blocks[i].n_packets;
 
 
         off += viv->sb_blocks[i].size;
         poff += viv->sb_blocks[i].n_packets;
 
-
         if (maxnp < viv->sb_blocks[i].n_packets)
             maxnp = viv->sb_blocks[i].n_packets;
     }
 
         if (maxnp < viv->sb_blocks[i].n_packets)
             maxnp = viv->sb_blocks[i].n_packets;
     }
 
+    if (filesize > 0 && poff > filesize)
+        goto error;
+
     viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
     av_free(pb);
 
     return 0;
     viv->sb_entries = av_calloc(maxnp, sizeof(VIV_SB_entry));
     av_free(pb);
 
     return 0;
+error:
+    av_free(pb);
+    viv->n_sb_blocks = 0;
+    av_freep(&viv->sb_blocks);
+    return AVERROR_INVALIDDATA;
 }
 
 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)
 }
 
 static void load_sb_block(AVFormatContext *s, VividasDemuxContext *viv, unsigned expected_size)