summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2019-12-07 00:16:19 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2020-07-02 10:04:24 +0200
commitad1947103b621b7e562e9839a60cabe87cc3793f (patch)
tree62a195eb785af370fe1d0309504ff4eaf2785bdb
parent65dd486a4270d5cefcc45c6cb8e21f04333691c2 (diff)
downloadffmpeg-ad1947103b621b7e562e9839a60cabe87cc3793f.tar.gz
avformat/matroskadec: Fix use-after-free when demuxing ProRes
ProRes in Matroska is supposed to not contain the first atom header (containing a size field and the tag "icpf") and therefore the Matroska demuxer has to recreate it; this involves an allocation and copy, of course. Whether the old buffer (containing the data without the atom header) needs to be freed or not depends upon whether it is what was directly read (in which case it is owned by an AVBuffer) or whether it has been allocated when reversing the track's content compression (e.g. zlib compression) that Matroska supports. So there are three pointers involved: The one pointing to the directly read data (owned by the AVBuffer), the one pointing to the currently valid data (which coincides with the former if no content compression needed to be reverted) and the one pointing to the new data with the first atom header. The check for whether to free the second of these is simply whether the first two are different. This works mostly, but there is a complication: Some muxers don't strip the first atom header away and in this case, it is also not reinserted and no new buffer is allocated; instead, the second and the third pointers agree. In this case, one must never free the second buffer. Yet it is currently done if the track is e.g. zlib compressed. This commit fixes this. This is a regression since b8e75a2a. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com> Signed-off-by: James Almer <jamrial@gmail.com> (cherry picked from commit af50f0a515d8096fece9776e2d3034fe990a1373) Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
-rw-r--r--libavformat/matroskadec.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index a66b05409c..ce3ef653b7 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -3043,11 +3043,8 @@ fail:
static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src,
uint8_t **pdst, int *size)
{
- uint8_t *dst = src;
- int dstlen = *size;
-
- if (AV_RB32(&src[4]) != MKBETAG('i', 'c', 'p', 'f')) {
- dstlen += 8;
+ uint8_t *dst;
+ int dstlen = *size + 8;
dst = av_malloc(dstlen + AV_INPUT_BUFFER_PADDING_SIZE);
if (!dst)
@@ -3057,7 +3054,6 @@ static int matroska_parse_prores(MatroskaTrack *track, uint8_t *src,
AV_WB32(dst + 4, MKBETAG('i', 'c', 'p', 'f'));
memcpy(dst + 8, src, dstlen - 8);
memset(dst + dstlen, 0, AV_INPUT_BUFFER_PADDING_SIZE);
- }
*pdst = dst;
*size = dstlen;
@@ -3212,7 +3208,8 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska,
pkt_data = wv_data;
}
- if (st->codecpar->codec_id == AV_CODEC_ID_PRORES) {
+ if (st->codecpar->codec_id == AV_CODEC_ID_PRORES &&
+ AV_RB32(pkt_data + 4) != MKBETAG('i', 'c', 'p', 'f')) {
uint8_t *pr_data;
res = matroska_parse_prores(track, pkt_data, &pr_data, &pkt_size);
if (res < 0) {