From: Michael Niedermayer Date: Sat, 28 Nov 2015 18:08:46 +0000 (+0100) Subject: avcodec/utils: Clear dimensions in ff_get_buffer() on failure X-Git-Tag: archive/raspbian/6%11.12-1_deb8u8+rpi1^2~42 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=75730d771144096cc3ef0d6ce62fdb0fc65baed8;p=libav.git avcodec/utils: Clear dimensions in ff_get_buffer() on failure avcodec/utils: Clear dimensions in ff_get_buffer() on failure Fixes out of array access Fixes: 482d8f2fd17c9f532b586458a33f267c/asan_heap-oob_4a52b6_7417_1d08d477736d66cdadd833d146bb8bae.mov Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer [sunweaver] - manually adapted for Debian jessie's libav version which lacks the get_internal_buffer() symbol. Gbp-Pq: Name CVE-2015-8663.patch --- diff --git a/libavcodec/utils.c b/libavcodec/utils.c index c5fa50d..ba29f63 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -617,6 +617,10 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) switch (avctx->codec_type) { case AVMEDIA_TYPE_VIDEO: + if (av_image_check_size(avctx->width, avctx->height, 0, avctx) < 0) { + frame->width = frame->height = 0; + return AVERROR(EINVAL); + } if (frame->width <= 0 || frame->height <= 0) { frame->width = FFMAX(avctx->width, avctx->coded_width); frame->height = FFMAX(avctx->height, avctx->coded_height); @@ -634,9 +638,6 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) frame->sample_aspect_ratio.den); frame->sample_aspect_ratio = (AVRational){ 0, 1 }; } - - if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) - return ret; break; case AVMEDIA_TYPE_AUDIO: if (!frame->sample_rate) @@ -670,8 +671,11 @@ int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) } ret = ff_decode_frame_props(avctx, frame); - if (ret < 0) + if (ret < 0) { + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) + frame->width = frame->height = 0; return ret; + } if (hwaccel && hwaccel->alloc_frame) { ret = hwaccel->alloc_frame(avctx, frame); @@ -696,8 +700,11 @@ FF_DISABLE_DEPRECATION_WARNINGS frame->reference = 1; ret = avctx->get_buffer(avctx, frame); - if (ret < 0) + if (ret < 0) { + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) + frame->width = frame->height = 0; return ret; + } /* return if the buffers are already set up * this would happen e.g. when a custom get_buffer() calls @@ -789,6 +796,8 @@ fail: avctx->release_buffer(avctx, frame); av_freep(&priv); av_buffer_unref(&dummy_buf); + if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) + frame->width = frame->height = 0; return ret; } FF_ENABLE_DEPRECATION_WARNINGS @@ -802,6 +811,9 @@ end: frame->height = avctx->height; } + if ((ret < 0) && (avctx->codec_type == AVMEDIA_TYPE_VIDEO)) + frame->width = frame->height = 0; + return ret; }