diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-08-30 06:51:09 +0400 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2014-08-12 14:21:21 +0400 |
commit | da7d839a0d3ec40423a665dc85e0cfaed3f92eb8 (patch) | |
tree | 744eb020c08fa725554f26f53b82bc6d40470d9f | |
parent | 3187fa14a326908f9471a038e3b5b24c0eaf655e (diff) |
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 <anton@khirnov.net>
-rw-r--r-- | libavcodec/ffv1dec.c | 32 |
1 files 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->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; + } + } - if (f->version > 0) - f->avctx->bits_per_raw_sample = get_symbol(c, state, 0); + 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; } |