summaryrefslogtreecommitdiff
path: root/libavformat/mov.c
diff options
context:
space:
mode:
authorDale Curtis <dalecurtis@chromium.org>2015-01-06 04:00:43 +0100
committerMichael Niedermayer <michaelni@gmx.at>2015-01-06 04:44:16 +0100
commitdb42d93a61be26873be6115c57f5921b4dfdec14 (patch)
tree74b5e688536d436b9ed1590d0331ebb3df06fc84 /libavformat/mov.c
parenta79ac73b631a2d8347f45fbdcb666f37e40ab9fe (diff)
mov: Fix overflow and error handling in read_tfra().
Under abnormal conditions the item_count may exceed the max allocation size on 32-bit systems, this causes the allocated size to overflow and become too small for the given count. Additionally, if av_reallocp() fails its allocation, the fragment_index_count is not correctly decremented. Ensuring further havoc may be wrought, the error code for read_tfra() is not checked upon return. Found-by: Paul Mehta <paul@paulmehta.com> positive return code and use of _array functions by commiter Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r--libavformat/mov.c36
1 files changed, 21 insertions, 15 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c
index f2d4fa0ae9..ba79378cd6 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -3823,35 +3823,39 @@ static void export_orphan_timecode(AVFormatContext *s)
static int read_tfra(MOVContext *mov, AVIOContext *f)
{
MOVFragmentIndex* index = NULL;
- int version, fieldlength, i, j, err;
+ int version, fieldlength, i, j;
int64_t pos = avio_tell(f);
uint32_t size = avio_rb32(f);
+ void *tmp;
+
if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
- return -1;
+ return 1;
}
av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
index = av_mallocz(sizeof(MOVFragmentIndex));
if (!index) {
return AVERROR(ENOMEM);
}
- mov->fragment_index_count++;
- if ((err = av_reallocp(&mov->fragment_index_data,
- mov->fragment_index_count *
- sizeof(MOVFragmentIndex*))) < 0) {
+
+ tmp = av_realloc_array(mov->fragment_index_data,
+ mov->fragment_index_count + 1,
+ sizeof(MOVFragmentIndex*));
+ if (!tmp) {
av_freep(&index);
- return err;
+ return AVERROR(ENOMEM);
}
- mov->fragment_index_data[mov->fragment_index_count - 1] =
- index;
+ mov->fragment_index_data = tmp;
+ mov->fragment_index_data[mov->fragment_index_count++] = index;
version = avio_r8(f);
avio_rb24(f);
index->track_id = avio_rb32(f);
fieldlength = avio_rb32(f);
index->item_count = avio_rb32(f);
- index->items = av_mallocz(
- index->item_count * sizeof(MOVFragmentIndexItem));
+ index->items = av_mallocz_array(
+ index->item_count, sizeof(MOVFragmentIndexItem));
if (!index->items) {
+ index->item_count = 0;
return AVERROR(ENOMEM);
}
for (i = 0; i < index->item_count; i++) {
@@ -3905,11 +3909,13 @@ static int mov_read_mfra(MOVContext *c, AVIOContext *f)
av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
goto fail;
}
- ret = 0;
av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
- while (!read_tfra(c, f)) {
- /* Empty */
- }
+ do {
+ ret = read_tfra(c, f);
+ if (ret < 0)
+ goto fail;
+ } while (!ret);
+ ret = 0;
fail:
seek_ret = avio_seek(f, original_pos, SEEK_SET);
if (seek_ret < 0) {