ref: 09b0228f634999f13995d9a4cf47142098aff3bd
parent: cfb21cfbafc8cabe978f938d75ea8b0ce6c4295c
author: knik <knik@users.sourceforge.net>
date: Tue Jul 11 04:12:10 EDT 2017
Working patch to fix previous broken commit "multiple vulnerabilities"
--- a/common/mp4ff/mp4atom.c
+++ b/common/mp4ff/mp4atom.c
@@ -242,6 +242,9 @@
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)
{
@@ -258,11 +261,17 @@
static int32_t mp4ff_read_stsz(mp4ff_t *f)
{
+ if (f->total_tracks == 0)
+ return -1;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
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;
@@ -283,6 +292,9 @@
uint8_t tag;
uint32_t temp;
+ if (f->total_tracks == 0)
+ return -1;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
@@ -347,6 +359,9 @@
uint8_t atom_type = 0;
uint8_t header_size = 0;
+ if (f->total_tracks == 0)
+ return -1;
+
for (i = 0; i < 6; i++)
{
mp4ff_read_char(f); /* reserved */
@@ -380,11 +395,17 @@
int32_t i;
uint8_t header_size = 0;
+ if (f->total_tracks == 0)
+ return -1;
+
mp4ff_read_char(f); /* version */
mp4ff_read_int24(f); /* flags */
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++)
{
uint64_t skip = mp4ff_position(f);
@@ -415,10 +436,16 @@
{
int32_t i;
+ if (f->total_tracks == 0)
+ return -1;
+
mp4ff_read_char(f); /* version */
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 =
@@ -440,10 +467,16 @@
{
int32_t i;
+ if (f->total_tracks == 0)
+ return -1;
+
mp4ff_read_char(f); /* version */
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));
@@ -458,8 +491,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 -1;
+
+ p_track = f->track[f->total_tracks - 1];
if (p_track->ctts_entry_count) return 0;
mp4ff_read_char(f); /* version */
@@ -466,6 +503,9 @@
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));
@@ -490,8 +530,13 @@
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;
+ if (f->total_tracks == 0)
+ return -1;
+
+ p_track = f->track[f->total_tracks - 1];
+
if (p_track->stts_entry_count) return 0;
mp4ff_read_char(f); /* version */
@@ -498,6 +543,9 @@
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));
@@ -597,6 +645,9 @@
{
uint32_t version;
+ if (f->total_tracks == 0)
+ return -1;
+
version = mp4ff_read_int32(f);
if (version==1)
{
@@ -626,6 +677,9 @@
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 */
@@ -650,39 +704,36 @@
int32_t mp4ff_atom_read(mp4ff_t *f, const int32_t size, const uint8_t atom_type)
{
uint64_t dest_position = mp4ff_position(f)+size-8;
- if (f->total_tracks == 0)
- {
- return -1;
- }
+ int32_t ret = 0;
if (atom_type == ATOM_STSZ)
{
/* sample size box */
- mp4ff_read_stsz(f);
+ ret = mp4ff_read_stsz(f);
} else if (atom_type == ATOM_STTS) {
/* time to sample box */
- mp4ff_read_stts(f);
+ ret = mp4ff_read_stts(f);
} else if (atom_type == ATOM_CTTS) {
/* composition offset box */
- mp4ff_read_ctts(f);
+ ret = mp4ff_read_ctts(f);
} else if (atom_type == ATOM_STSC) {
/* sample to chunk box */
- mp4ff_read_stsc(f);
+ ret = mp4ff_read_stsc(f);
} else if (atom_type == ATOM_STCO) {
/* chunk offset box */
- mp4ff_read_stco(f);
+ ret = mp4ff_read_stco(f);
} else if (atom_type == ATOM_STSD) {
/* sample description box */
- mp4ff_read_stsd(f);
+ ret = mp4ff_read_stsd(f);
} else if (atom_type == ATOM_MVHD) {
/* movie header box */
- mp4ff_read_mvhd(f);
+ ret = mp4ff_read_mvhd(f);
} else if (atom_type == ATOM_MDHD) {
/* track header */
- mp4ff_read_mdhd(f);
+ ret = mp4ff_read_mdhd(f);
#ifdef USE_TAGGING
} else if (atom_type == ATOM_META) {
/* iTunes Metadata box */
- mp4ff_read_meta(f, size);
+ ret = mp4ff_read_meta(f, size);
#endif
}
@@ -689,5 +740,5 @@
mp4ff_set_position(f, dest_position);
- return 0;
+ return ret;
}
--- a/common/mp4ff/mp4ff.c
+++ b/common/mp4ff/mp4ff.c
@@ -29,9 +29,24 @@
**/
#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));
@@ -39,6 +54,7 @@
memset(ff, 0, sizeof(mp4ff_t));
ff->stream = f;
+ ff->actual_file_size = actual_file_size(f);
if (parse_atoms(ff,0) < 0)
{
@@ -56,6 +72,7 @@
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,6 +223,7 @@
uint64_t moov_size;
uint8_t last_atom;
uint64_t file_size;
+ uint64_t actual_file_size;
/* mvhd */
int32_t time_scale;