Patrick Williams | c124f4f | 2015-09-15 14:41:29 -0500 | [diff] [blame] | 1 | Upstream-Status: Backport |
| 2 | |
| 3 | Backport patch to fix CVE-2014-9676. |
| 4 | |
| 5 | https://security-tracker.debian.org/tracker/CVE-2014-9676 |
| 6 | https://git.libav.org/?p=libav.git;a=commit;h=b3f04657368a32a9903406395f865e230b1de348 |
| 7 | |
| 8 | Signed-off-by: Kai Kang <kai.kang@windriver.com> |
| 9 | --- |
| 10 | From b3f04657368a32a9903406395f865e230b1de348 Mon Sep 17 00:00:00 2001 |
| 11 | From: Luca Barbato <lu_zero@gentoo.org> |
| 12 | Date: Mon, 5 Jan 2015 10:40:41 +0100 |
| 13 | Subject: [PATCH] segment: Fix the failure paths |
| 14 | |
| 15 | A failure in segment_end() or segment_start() would lead to freeing |
| 16 | a dangling pointer and in general further calls to seg_write_packet() |
| 17 | or to seg_write_trailer() would have the same faulty behaviour. |
| 18 | |
| 19 | CC: libav-stable@libav.org |
| 20 | Reported-By: luodalongde@gmail.com |
| 21 | --- |
| 22 | libavformat/segment.c | 32 ++++++++++++++++++++------------ |
| 23 | 1 file changed, 20 insertions(+), 12 deletions(-) |
| 24 | |
| 25 | diff --git a/libavformat/segment.c b/libavformat/segment.c |
| 26 | index 52da6b9..bcfd1f9 100644 |
| 27 | --- a/libavformat/segment.c |
| 28 | +++ b/libavformat/segment.c |
| 29 | @@ -184,6 +184,13 @@ static void close_null_ctx(AVIOContext *pb) |
| 30 | av_free(pb); |
| 31 | } |
| 32 | |
| 33 | +static void seg_free_context(SegmentContext *seg) |
| 34 | +{ |
| 35 | + avio_closep(&seg->pb); |
| 36 | + avformat_free_context(seg->avf); |
| 37 | + seg->avf = NULL; |
| 38 | +} |
| 39 | + |
| 40 | static int seg_write_header(AVFormatContext *s) |
| 41 | { |
| 42 | SegmentContext *seg = s->priv_data; |
| 43 | @@ -265,12 +272,9 @@ static int seg_write_header(AVFormatContext *s) |
| 44 | } |
| 45 | |
| 46 | fail: |
| 47 | - if (ret) { |
| 48 | - if (seg->list) |
| 49 | - avio_close(seg->pb); |
| 50 | - if (seg->avf) |
| 51 | - avformat_free_context(seg->avf); |
| 52 | - } |
| 53 | + if (ret < 0) |
| 54 | + seg_free_context(seg); |
| 55 | + |
| 56 | return ret; |
| 57 | } |
| 58 | |
| 59 | @@ -282,6 +286,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) |
| 60 | int64_t end_pts = seg->recording_time * seg->number; |
| 61 | int ret, can_split = 1; |
| 62 | |
| 63 | + if (!oc) |
| 64 | + return AVERROR(EINVAL); |
| 65 | + |
| 66 | if (seg->has_video) { |
| 67 | can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && |
| 68 | pkt->flags & AV_PKT_FLAG_KEY; |
| 69 | @@ -322,11 +329,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) |
| 70 | ret = ff_write_chained(oc, pkt->stream_index, pkt, s); |
| 71 | |
| 72 | fail: |
| 73 | - if (ret < 0) { |
| 74 | - if (seg->list) |
| 75 | - avio_close(seg->pb); |
| 76 | - avformat_free_context(oc); |
| 77 | - } |
| 78 | + if (ret < 0) |
| 79 | + seg_free_context(seg); |
| 80 | |
| 81 | return ret; |
| 82 | } |
| 83 | @@ -335,7 +339,11 @@ static int seg_write_trailer(struct AVFormatContext *s) |
| 84 | { |
| 85 | SegmentContext *seg = s->priv_data; |
| 86 | AVFormatContext *oc = seg->avf; |
| 87 | - int ret; |
| 88 | + int ret = 0; |
| 89 | + |
| 90 | + if (!oc) |
| 91 | + goto fail; |
| 92 | + |
| 93 | if (!seg->write_header_trailer) { |
| 94 | if ((ret = segment_end(oc, 0)) < 0) |
| 95 | goto fail; |
| 96 | -- |
| 97 | 2.4.1.314.g9532ead |
| 98 | |