From da7d839a0d3ec40423a665dc85e0cfaed3f92eb8 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 30 Aug 2013 04:51:09 +0200 Subject: [PATCH] ffv1dec: check that global parameters do not change in version 0/1 Such changes are neither allowed nor supported Found-by: ami_stuff Bug-Id: CVE-2013-7020 CC: libav-stable@libav.org Signed-off-by: Anton Khirnov --- libavcodec/ffv1dec.c | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 703491ecd8..50b220ff07 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -550,6 +550,7 @@ static int read_header(FFV1Context *f) memset(state, 128, sizeof(state)); if (f->version < 2) { + int chroma_planes, chroma_h_shift, chroma_v_shift, transparency, colorspace, bits_per_raw_sample; unsigned v = get_symbol(c, state, 0); if (v > 1) { av_log(f->avctx, AV_LOG_ERROR, @@ -566,15 +567,32 @@ static int read_header(FFV1Context *f) get_symbol(c, state, 1) + c->one_state[i]; } - f->colorspace = get_symbol(c, state, 0); //YUV cs type + colorspace = get_symbol(c, state, 0); //YUV cs type + bits_per_raw_sample = f->version > 0 ? get_symbol(c, state, 0) : f->avctx->bits_per_raw_sample; + chroma_planes = get_rac(c, state); + chroma_h_shift = get_symbol(c, state, 0); + chroma_v_shift = get_symbol(c, state, 0); + transparency = get_rac(c, state); - if (f->version > 0) - f->avctx->bits_per_raw_sample = get_symbol(c, state, 0); + if (f->plane_count) { + if (colorspace != f->colorspace || + bits_per_raw_sample != f->avctx->bits_per_raw_sample || + chroma_planes != f->chroma_planes || + chroma_h_shift != f->chroma_h_shift || + chroma_v_shift != f->chroma_v_shift || + transparency != f->transparency) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid change of global parameters\n"); + return AVERROR_INVALIDDATA; + } + } + + f->colorspace = colorspace; + f->avctx->bits_per_raw_sample = bits_per_raw_sample; + f->chroma_planes = chroma_planes; + f->chroma_h_shift = chroma_h_shift; + f->chroma_v_shift = chroma_v_shift; + f->transparency = transparency; - f->chroma_planes = get_rac(c, state); - f->chroma_h_shift = get_symbol(c, state, 0); - f->chroma_v_shift = get_symbol(c, state, 0); - f->transparency = get_rac(c, state); f->plane_count = 2 + f->transparency; }