shithub: aacdec

Download patch

ref: 7c348bdbd1424d5a088507b9cca665bf9609b040
parent: 09b0228f634999f13995d9a4cf47142098aff3bd
author: knik <knik@users.sourceforge.net>
date: Wed Jul 12 06:06:57 EDT 2017

hopefully the last patch in the "multiple vulnerabilities" series

--- a/common/mp4ff/mp4atom.c
+++ b/common/mp4ff/mp4atom.c
@@ -242,9 +242,6 @@
     size = mp4ff_atom_get_size(atom_header);
     *header_size = 8;
 
-    if (size > f->actual_file_size)
-        return 0;
-
     /* check for 64 bit atom size */
     if (size == 1)
     {
@@ -269,9 +266,6 @@
     f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
     f->track[f->total_tracks - 1]->stsz_sample_count = mp4ff_read_int32(f);
 
-    if (f->track[f->total_tracks - 1]->stsz_sample_count > f->actual_file_size)
-        return -1;
-
     if (f->track[f->total_tracks - 1]->stsz_sample_size == 0)
     {
         int32_t i;
@@ -278,7 +272,10 @@
         f->track[f->total_tracks - 1]->stsz_table =
             (int32_t*)malloc(f->track[f->total_tracks - 1]->stsz_sample_count*sizeof(int32_t));
 
-        for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count; i++)
+        if (!f->track[f->total_tracks - 1]->stsz_table)
+            return -1;
+
+        for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count && !f->read_error; i++)
         {
             f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
         }
@@ -403,10 +400,7 @@
 
     f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
 
-    if (f->track[f->total_tracks - 1]->stsd_entry_count > f->actual_file_size)
-        return -1;
-
-    for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
+    for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count && !f->read_error; i++)
     {
         uint64_t skip = mp4ff_position(f);
         uint64_t size;
@@ -443,9 +437,6 @@
     mp4ff_read_int24(f); /* flags */
     f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
 
-    if (f->track[f->total_tracks - 1]->stsc_entry_count > f->actual_file_size)
-        return -1;
-
     f->track[f->total_tracks - 1]->stsc_first_chunk =
         (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
     f->track[f->total_tracks - 1]->stsc_samples_per_chunk =
@@ -453,8 +444,27 @@
     f->track[f->total_tracks - 1]->stsc_sample_desc_index =
         (int32_t*)malloc(f->track[f->total_tracks - 1]->stsc_entry_count*sizeof(int32_t));
 
-    for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count; i++)
+    if (!f->track[f->total_tracks - 1]->stsc_first_chunk)
     {
+        return -1;
+    }
+    if (!f->track[f->total_tracks - 1]->stsc_samples_per_chunk)
+    {
+        free(f->track[f->total_tracks - 1]->stsc_first_chunk);
+        f->track[f->total_tracks - 1]->stsc_first_chunk = NULL;
+        return -1;
+    }
+    if (!f->track[f->total_tracks - 1]->stsc_sample_desc_index)
+    {
+        free(f->track[f->total_tracks - 1]->stsc_first_chunk);
+        f->track[f->total_tracks - 1]->stsc_first_chunk = NULL;
+        free(f->track[f->total_tracks - 1]->stsc_samples_per_chunk);
+        f->track[f->total_tracks - 1]->stsc_samples_per_chunk = NULL;
+        return -1;
+    }
+
+    for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count && !f->read_error; i++)
+    {
         f->track[f->total_tracks - 1]->stsc_first_chunk[i] = mp4ff_read_int32(f);
         f->track[f->total_tracks - 1]->stsc_samples_per_chunk[i] = mp4ff_read_int32(f);
         f->track[f->total_tracks - 1]->stsc_sample_desc_index[i] = mp4ff_read_int32(f);
@@ -474,13 +484,13 @@
     mp4ff_read_int24(f); /* flags */
     f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
 
-    if (f->track[f->total_tracks - 1]->stco_entry_count > f->actual_file_size)
-        return -1;
-
     f->track[f->total_tracks - 1]->stco_chunk_offset =
         (int32_t*)malloc(f->track[f->total_tracks - 1]->stco_entry_count*sizeof(int32_t));
 
-    for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count; i++)
+    if (!f->track[f->total_tracks - 1]->stco_chunk_offset)
+        return -1;
+
+    for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count && !f->read_error; i++)
     {
         f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
     }
@@ -503,9 +513,6 @@
     mp4ff_read_int24(f); /* flags */
     p_track->ctts_entry_count = mp4ff_read_int32(f);
 
-    if (f->track[f->total_tracks - 1]->ctts_entry_count > f->actual_file_size)
-        return -1;
-
     p_track->ctts_sample_count = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
     p_track->ctts_sample_offset = (int32_t*)malloc(p_track->ctts_entry_count * sizeof(int32_t));
 
@@ -518,7 +525,7 @@
     }
     else
     {
-        for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count; i++)
+        for (i = 0; i < f->track[f->total_tracks - 1]->ctts_entry_count && !f->read_error; i++)
         {
             p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
             p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
@@ -543,9 +550,6 @@
     mp4ff_read_int24(f); /* flags */
     p_track->stts_entry_count = mp4ff_read_int32(f);
 
-    if (f->track[f->total_tracks - 1]->stts_entry_count > f->actual_file_size)
-        return -1;
-
     p_track->stts_sample_count = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
     p_track->stts_sample_delta = (int32_t*)malloc(p_track->stts_entry_count * sizeof(int32_t));
 
@@ -558,7 +562,7 @@
     }
     else
     {
-        for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count; i++)
+        for (i = 0; i < f->track[f->total_tracks - 1]->stts_entry_count && !f->read_error; i++)
         {
             p_track->stts_sample_count[i] = mp4ff_read_int32(f);
             p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
@@ -677,13 +681,10 @@
     uint8_t atom_type;
     uint8_t header_size = 0;
 
-    if (size > f->actual_file_size)
-        return -1;
-
     mp4ff_read_char(f); /* version */
     mp4ff_read_int24(f); /* flags */
 
-    while (sumsize < (size-(header_size+4)))
+    while (sumsize < (size-(header_size+4)) && !f->read_error)
     {
         subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
         if (subsize <= header_size+4)
@@ -736,6 +737,9 @@
         ret = mp4ff_read_meta(f, size);
 #endif
     }
+
+    if (f->read_error)
+        ret = -1;
 
     mp4ff_set_position(f, dest_position);
 
--- a/common/mp4ff/mp4ff.c
+++ b/common/mp4ff/mp4ff.c
@@ -29,24 +29,9 @@
 **/
 
 #include <stdlib.h>
-#include <stdio.h>
 #include <string.h>
 #include "mp4ffint.h"
 
-static uint64_t actual_file_size(mp4ff_callback_t *f)
-{
-    int64_t cur_pos, end_pos;
-
-    cur_pos = ftell(f->user_data);
-
-    fseek(f->user_data, 0, SEEK_END);
-    end_pos = ftell(f->user_data);
-
-    fseek(f->user_data, cur_pos, SEEK_SET);
-
-    return end_pos;
-}
-
 mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f)
 {
     mp4ff_t *ff = malloc(sizeof(mp4ff_t));
@@ -54,7 +39,6 @@
     memset(ff, 0, sizeof(mp4ff_t));
 
     ff->stream = f;
-    ff->actual_file_size = actual_file_size(f);
 
     if (parse_atoms(ff,0) < 0)
     {
@@ -72,7 +56,6 @@
     memset(ff, 0, sizeof(mp4ff_t));
 
     ff->stream = f;
-    ff->actual_file_size = actual_file_size(f);
 
     if (parse_atoms(ff,1) < 0)
     {
--- a/common/mp4ff/mp4ffint.h
+++ b/common/mp4ff/mp4ffint.h
@@ -223,7 +223,7 @@
     uint64_t moov_size;
     uint8_t last_atom;
     uint64_t file_size;
-    uint64_t actual_file_size;
+    int32_t read_error;
 
     /* mvhd */
     int32_t time_scale;
--- a/common/mp4ff/mp4meta.c
+++ b/common/mp4ff/mp4meta.c
@@ -240,7 +240,7 @@
     uint32_t len = 0;
 
 
-    while (sumsize < size)
+    while (sumsize < size && !f->read_error)
     {
 		uint64_t destpos;
         subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
@@ -343,7 +343,7 @@
     uint8_t atom_type;
     uint8_t header_size = 0;
 
-    while (sumsize < size)
+    while (sumsize < size && !f->read_error)
     {
         subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
         if (subsize == 0)
@@ -500,4 +500,4 @@
     return mp4ff_meta_find_by_name_and_return_len(f, "cover", value);
 }
 
-#endif
\ No newline at end of file
+#endif
--- a/common/mp4ff/mp4util.c
+++ b/common/mp4ff/mp4util.c
@@ -37,6 +37,9 @@
 
     result = f->stream->read(f->stream->user_data, data, size);
 
+    if (result < size)
+        f->read_error++;
+
     f->current_position += size;
 
     return result;