[FFmpeg-cvslog] mov: Fix overflow and error handling in read_tfra().
ffmpeg | branch: release/2.5 | Dale Curtis | Tue Jan 6 04:00:43 2015 +0100| [9143ab0e5a75519c899cae2996d07b3f69bcfb24] | committer: Michael Niedermayer 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 positive return code and use of _array functions by commiter Signed-off-by: Michael Niedermayer (cherry picked from commit db42d93a61be26873be6115c57f5921b4dfdec14) Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=9143ab0e5a75519c899cae2996d07b3f69bcfb24 --- libavformat/mov.c | 36 +--- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index b888c67..3a93897 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -3782,35 +3782,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++) { @@ -3864,11 +3868,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) { ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog
[FFmpeg-cvslog] mov: Fix overflow and error handling in read_tfra().
ffmpeg | branch: master | Dale Curtis | Tue Jan 6 04:00:43 2015 +0100| [db42d93a61be26873be6115c57f5921b4dfdec14] | committer: Michael Niedermayer 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 positive return code and use of _array functions by commiter Signed-off-by: Michael Niedermayer > http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=db42d93a61be26873be6115c57f5921b4dfdec14 --- libavformat/mov.c | 36 +--- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/libavformat/mov.c b/libavformat/mov.c index f2d4fa0..ba79378 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) { ___ ffmpeg-cvslog mailing list ffmpeg-cvslog@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-cvslog