| Upstream-Status: Backport |
| |
| Backport patch to fix CVE-2014-9676. |
| |
| https://security-tracker.debian.org/tracker/CVE-2014-9676 |
| https://git.libav.org/?p=libav.git;a=commit;h=b3f04657368a32a9903406395f865e230b1de348 |
| |
| Signed-off-by: Kai Kang <kai.kang@windriver.com> |
| --- |
| From b3f04657368a32a9903406395f865e230b1de348 Mon Sep 17 00:00:00 2001 |
| From: Luca Barbato <lu_zero@gentoo.org> |
| Date: Mon, 5 Jan 2015 10:40:41 +0100 |
| Subject: [PATCH] segment: Fix the failure paths |
| |
| A failure in segment_end() or segment_start() would lead to freeing |
| a dangling pointer and in general further calls to seg_write_packet() |
| or to seg_write_trailer() would have the same faulty behaviour. |
| |
| CC: libav-stable@libav.org |
| Reported-By: luodalongde@gmail.com |
| --- |
| libavformat/segment.c | 32 ++++++++++++++++++++------------ |
| 1 file changed, 20 insertions(+), 12 deletions(-) |
| |
| diff --git a/libavformat/segment.c b/libavformat/segment.c |
| index 52da6b9..bcfd1f9 100644 |
| --- a/libavformat/segment.c |
| +++ b/libavformat/segment.c |
| @@ -184,6 +184,13 @@ static void close_null_ctx(AVIOContext *pb) |
| av_free(pb); |
| } |
| |
| +static void seg_free_context(SegmentContext *seg) |
| +{ |
| + avio_closep(&seg->pb); |
| + avformat_free_context(seg->avf); |
| + seg->avf = NULL; |
| +} |
| + |
| static int seg_write_header(AVFormatContext *s) |
| { |
| SegmentContext *seg = s->priv_data; |
| @@ -265,12 +272,9 @@ static int seg_write_header(AVFormatContext *s) |
| } |
| |
| fail: |
| - if (ret) { |
| - if (seg->list) |
| - avio_close(seg->pb); |
| - if (seg->avf) |
| - avformat_free_context(seg->avf); |
| - } |
| + if (ret < 0) |
| + seg_free_context(seg); |
| + |
| return ret; |
| } |
| |
| @@ -282,6 +286,9 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) |
| int64_t end_pts = seg->recording_time * seg->number; |
| int ret, can_split = 1; |
| |
| + if (!oc) |
| + return AVERROR(EINVAL); |
| + |
| if (seg->has_video) { |
| can_split = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && |
| pkt->flags & AV_PKT_FLAG_KEY; |
| @@ -322,11 +329,8 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) |
| ret = ff_write_chained(oc, pkt->stream_index, pkt, s); |
| |
| fail: |
| - if (ret < 0) { |
| - if (seg->list) |
| - avio_close(seg->pb); |
| - avformat_free_context(oc); |
| - } |
| + if (ret < 0) |
| + seg_free_context(seg); |
| |
| return ret; |
| } |
| @@ -335,7 +339,11 @@ static int seg_write_trailer(struct AVFormatContext *s) |
| { |
| SegmentContext *seg = s->priv_data; |
| AVFormatContext *oc = seg->avf; |
| - int ret; |
| + int ret = 0; |
| + |
| + if (!oc) |
| + goto fail; |
| + |
| if (!seg->write_header_trailer) { |
| if ((ret = segment_end(oc, 0)) < 0) |
| goto fail; |
| -- |
| 2.4.1.314.g9532ead |
| |