ref: a67c75ed600cf4b41205d69664d3d9106e9c5380
parent: 062400233caf4dffbb462c8c0dc071fc2483bea2
author: knik <knik@users.sourceforge.net>
date: Mon Jul 17 05:28:47 EDT 2017
I really hope the patch for multiple vulnerabilities will work this time
--- a/common/mp4ff/mp4atom.c
+++ b/common/mp4ff/mp4atom.c
@@ -258,6 +258,9 @@
static int32_t mp4ff_read_stsz(mp4ff_t *f)
{
+ if (f->total_tracks == 0)
+ return f->error++;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
f->track[f->total_tracks - 1]->stsz_sample_size = mp4ff_read_int32(f);
@@ -269,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 f->error++;
+
+ for (i = 0; i < f->track[f->total_tracks - 1]->stsz_sample_count && !f->stream->read_error; i++)
{
f->track[f->total_tracks - 1]->stsz_table[i] = mp4ff_read_int32(f);
}
@@ -283,6 +289,9 @@
uint8_t tag;
uint32_t temp;
+ if (f->total_tracks == 0)
+ return f->error++;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
@@ -347,6 +356,9 @@
uint8_t atom_type = 0;
uint8_t header_size = 0;
+ if (f->total_tracks == 0)
+ return f->error++;
+
for (i = 0; i < 6; i++)
{
mp4ff_read_char(f); /* reserved */
@@ -380,12 +392,16 @@
int32_t i;
uint8_t header_size = 0;
+ /* CVE-2017-9218 */
+ if (f->total_tracks == 0)
+ return f->error++;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);
- 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->stream->read_error; i++) /* CVE-2017-9253 */
{
uint64_t skip = mp4ff_position(f);
uint64_t size;
@@ -415,6 +431,9 @@
{
int32_t i;
+ if (f->total_tracks == 0)
+ return f->error++;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
f->track[f->total_tracks - 1]->stsc_entry_count = mp4ff_read_int32(f);
@@ -426,8 +445,28 @@
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++)
+ /* CVE-2017-9219 */
+ if (!f->track[f->total_tracks - 1]->stsc_first_chunk)
{
+ return f->error++;
+ }
+ 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 f->error++;
+ }
+ 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 f->error++;
+ }
+
+ for (i = 0; i < f->track[f->total_tracks - 1]->stsc_entry_count && !f->stream->read_error; i++) /* CVE-2017-9255 */
+ {
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);
@@ -440,6 +479,9 @@
{
int32_t i;
+ if (f->total_tracks == 0)
+ return f->error++;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
f->track[f->total_tracks - 1]->stco_entry_count = mp4ff_read_int32(f);
@@ -447,7 +489,11 @@
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++)
+ /* CVE-2017-9220 */
+ if (!f->track[f->total_tracks - 1]->stco_chunk_offset)
+ return f->error++;
+
+ for (i = 0; i < f->track[f->total_tracks - 1]->stco_entry_count && !f->stream->read_error; i++) /* CVE-2017-9256 */
{
f->track[f->total_tracks - 1]->stco_chunk_offset[i] = mp4ff_read_int32(f);
}
@@ -458,8 +504,12 @@
static int32_t mp4ff_read_ctts(mp4ff_t *f)
{
int32_t i;
- mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
+ mp4ff_track_t * p_track;
+ if (f->total_tracks == 0)
+ return f->error++;
+
+ p_track = f->track[f->total_tracks - 1];
if (p_track->ctts_entry_count) return 0;
mp4ff_read_char(f); /* version */
@@ -478,7 +528,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->stream->read_error; i++) /* CVE-2017-9257 */
{
p_track->ctts_sample_count[i] = mp4ff_read_int32(f);
p_track->ctts_sample_offset[i] = mp4ff_read_int32(f);
@@ -490,8 +540,14 @@
static int32_t mp4ff_read_stts(mp4ff_t *f)
{
int32_t i;
- mp4ff_track_t * p_track = f->track[f->total_tracks - 1];
+ mp4ff_track_t * p_track;
+ /* CVE-2017-9223 */
+ if (f->total_tracks == 0)
+ return f->error++;
+
+ p_track = f->track[f->total_tracks - 1];
+
if (p_track->stts_entry_count) return 0;
mp4ff_read_char(f); /* version */
@@ -510,7 +566,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->stream->read_error; i++) /* CVE-2017-9254 */
{
p_track->stts_sample_count[i] = mp4ff_read_int32(f);
p_track->stts_sample_delta[i] = mp4ff_read_int32(f);
@@ -596,6 +652,10 @@
static int32_t mp4ff_read_mdhd(mp4ff_t *f)
{
uint32_t version;
+
+ /* CVE-2017-9221 */
+ if (f->total_tracks == 0)
+ return f->error++;
version = mp4ff_read_int32(f);
if (version==1)
--- a/common/mp4ff/mp4ff.c
+++ b/common/mp4ff/mp4ff.c
@@ -42,6 +42,12 @@
parse_atoms(ff,0);
+ if (ff->error)
+ {
+ free(ff);
+ ff = NULL;
+ }
+
return ff;
}
@@ -55,6 +61,12 @@
parse_atoms(ff,1);
+ if (ff->error)
+ {
+ free(ff);
+ ff = NULL;
+ }
+
return ff;
}
@@ -101,10 +113,17 @@
if (ff) free(ff);
}
-void mp4ff_track_add(mp4ff_t *f)
+static void mp4ff_track_add(mp4ff_t *f)
{
f->total_tracks++;
+ if (f->total_tracks > MAX_TRACKS)
+ {
+ f->total_tracks = 0;
+ f->error++;
+ return;
+ }
+
f->track[f->total_tracks - 1] = malloc(sizeof(mp4ff_track_t));
memset(f->track[f->total_tracks - 1], 0, sizeof(mp4ff_track_t));
@@ -185,6 +204,7 @@
uint8_t header_size = 0;
f->file_size = 0;
+ f->stream->read_error = 0;
while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
{
--- a/common/mp4ff/mp4ff.h
+++ b/common/mp4ff/mp4ff.h
@@ -47,14 +47,115 @@
uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
uint32_t (*write)(void *udata, void *buffer, uint32_t length);
uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
+ uint32_t (*truncate)(void *user_data);
void *user_data;
+ uint32_t read_error;
} mp4ff_callback_t;
+#ifdef USE_TAGGING
+
+/* metadata tag structure */
+typedef struct
+{
+ char *item;
+ char *value;
+ uint32_t len;
+} mp4ff_tag_t;
+
+/* metadata list structure */
+typedef struct
+{
+ mp4ff_tag_t *tags;
+ uint32_t count;
+} mp4ff_metadata_t;
+
+int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
+
+#endif
+
+
+#ifndef MP4FF_INTERNAL_H
/* mp4 main file structure */
typedef void* mp4ff_t;
+#else
+typedef struct
+{
+ int32_t type;
+ int32_t channelCount;
+ int32_t sampleSize;
+ uint16_t sampleRate;
+ int32_t audioType;
+ /* stsd */
+ int32_t stsd_entry_count;
+ /* stsz */
+ int32_t stsz_sample_size;
+ int32_t stsz_sample_count;
+ int32_t *stsz_table;
+
+ /* stts */
+ int32_t stts_entry_count;
+ int32_t *stts_sample_count;
+ int32_t *stts_sample_delta;
+
+ /* stsc */
+ int32_t stsc_entry_count;
+ int32_t *stsc_first_chunk;
+ int32_t *stsc_samples_per_chunk;
+ int32_t *stsc_sample_desc_index;
+
+ /* stsc */
+ int32_t stco_entry_count;
+ int32_t *stco_chunk_offset;
+
+ /* ctts */
+ int32_t ctts_entry_count;
+ int32_t *ctts_sample_count;
+ int32_t *ctts_sample_offset;
+
+ /* esde */
+ uint8_t *decoderConfig;
+ int32_t decoderConfigLen;
+
+ uint32_t maxBitrate;
+ uint32_t avgBitrate;
+
+ uint32_t timeScale;
+ uint64_t duration;
+
+} mp4ff_track_t;
+
+/* mp4 main file structure */
+typedef struct
+{
+ /* stream to read from */
+ mp4ff_callback_t *stream;
+ int64_t current_position;
+
+ int32_t moov_read;
+ uint64_t moov_offset;
+ uint64_t moov_size;
+ uint8_t last_atom;
+ uint64_t file_size;
+ uint32_t error;
+
+ /* mvhd */
+ int32_t time_scale;
+ int32_t duration;
+
+ /* incremental track index while reading the file */
+ int32_t total_tracks;
+
+ /* track data */
+ mp4ff_track_t *track[MAX_TRACKS];
+
+ /* metadata */
+ mp4ff_metadata_t tags;
+} mp4ff_t;
+#endif
+
+
/* API */
mp4ff_t *mp4ff_open_read(mp4ff_callback_t *f);
@@ -110,26 +211,6 @@
int mp4ff_meta_get_compilation(const mp4ff_t *f, char **value);
int mp4ff_meta_get_tempo(const mp4ff_t *f, char **value);
int32_t mp4ff_meta_get_coverart(const mp4ff_t *f, char **value);
-#ifdef USE_TAGGING
-
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-
-int32_t mp4ff_meta_update(mp4ff_callback_t *f,const mp4ff_metadata_t * data);
-
-#endif
-
#ifdef __cplusplus
}
--- a/common/mp4ff/mp4ffint.h
+++ b/common/mp4ff/mp4ffint.h
@@ -136,110 +136,7 @@
#define strdup _strdup
#endif
-/* file callback structure */
-typedef struct
-{
- uint32_t (*read)(void *user_data, void *buffer, uint32_t length);
- uint32_t (*write)(void *udata, void *buffer, uint32_t length);
- uint32_t (*seek)(void *user_data, uint64_t position);
- uint32_t (*truncate)(void *user_data);
- void *user_data;
-} mp4ff_callback_t;
-
-
-/* metadata tag structure */
-typedef struct
-{
- char *item;
- char *value;
- uint32_t len;
-} mp4ff_tag_t;
-
-/* metadata list structure */
-typedef struct
-{
- mp4ff_tag_t *tags;
- uint32_t count;
-} mp4ff_metadata_t;
-
-
-typedef struct
-{
- int32_t type;
- int32_t channelCount;
- int32_t sampleSize;
- uint16_t sampleRate;
- int32_t audioType;
-
- /* stsd */
- int32_t stsd_entry_count;
-
- /* stsz */
- int32_t stsz_sample_size;
- int32_t stsz_sample_count;
- int32_t *stsz_table;
-
- /* stts */
- int32_t stts_entry_count;
- int32_t *stts_sample_count;
- int32_t *stts_sample_delta;
-
- /* stsc */
- int32_t stsc_entry_count;
- int32_t *stsc_first_chunk;
- int32_t *stsc_samples_per_chunk;
- int32_t *stsc_sample_desc_index;
-
- /* stsc */
- int32_t stco_entry_count;
- int32_t *stco_chunk_offset;
-
- /* ctts */
- int32_t ctts_entry_count;
- int32_t *ctts_sample_count;
- int32_t *ctts_sample_offset;
-
- /* esde */
- uint8_t *decoderConfig;
- int32_t decoderConfigLen;
-
- uint32_t maxBitrate;
- uint32_t avgBitrate;
-
- uint32_t timeScale;
- uint64_t duration;
-
-} mp4ff_track_t;
-
-/* mp4 main file structure */
-typedef struct
-{
- /* stream to read from */
- mp4ff_callback_t *stream;
- int64_t current_position;
-
- int32_t moov_read;
- uint64_t moov_offset;
- uint64_t moov_size;
- uint8_t last_atom;
- uint64_t file_size;
-
- /* mvhd */
- int32_t time_scale;
- int32_t duration;
-
- /* incremental track index while reading the file */
- int32_t total_tracks;
-
- /* track data */
- mp4ff_track_t *track[MAX_TRACKS];
-
- /* metadata */
- mp4ff_metadata_t tags;
-} mp4ff_t;
-
-
-
+#include "mp4ff.h"
/* mp4util.c */
int32_t mp4ff_read_data(mp4ff_t *f, int8_t *data, uint32_t size);
--- 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->stream->read_error) /* CVE-2017-9222 */
{
uint64_t destpos;
subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
@@ -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->stream->read_error++;
+
f->current_position += size;
return result;