diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-08-30 04:51:09 +0200 |
---|---|---|
committer | Anton Khirnov <anton@khirnov.net> | 2014-08-12 10:49:43 +0000 |
commit | b5d7b80a7e43779ca2962ba56442579c2a7e927d (patch) | |
tree | 6580bf79c26e369d66ec2fd77a311f7580ed85e4 /libavcodec/ffv1.c | |
parent | 452e343295e25f7b2cbc8529c66e9386e2ea6f55 (diff) | |
download | ffmpeg-b5d7b80a7e43779ca2962ba56442579c2a7e927d.tar.gz |
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>
(cherry picked from commit da7d839a0d3ec40423a665dc85e0cfaed3f92eb8)
Signed-off-by: Anton Khirnov <anton@khirnov.net>
Conflicts:
libavcodec/ffv1dec.c
Diffstat (limited to 'libavcodec/ffv1.c')
-rw-r--r-- | libavcodec/ffv1.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 917f40d1bc..5e798883b6 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -1518,20 +1518,45 @@ static int read_header(FFV1Context *f){ memset(state, 128, sizeof(state)); if(f->version < 2){ - f->version= get_symbol(c, state, 0); - f->ac= f->avctx->coder_type= get_symbol(c, state, 0); - if(f->ac>1){ - for(i=1; i<256; i++){ - f->state_transition[i]= get_symbol(c, state, 1) + c->one_state[i]; - } + int chroma_h_shift, chroma_v_shift, colorspace, bits_per_raw_sample; + unsigned v = get_symbol(c, state, 0); + if (v > 1) { + av_log(f->avctx, AV_LOG_ERROR, + "invalid version %d in version 1 header\n", v); + return AVERROR_INVALIDDATA; } - f->colorspace= get_symbol(c, state, 0); //YUV cs type - if(f->version>0) - f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); + f->version = v; + + f->ac = f->avctx->coder_type = get_symbol(c, state, 0); + + if (f->ac > 1) { + for (i = 1; i < 256; i++) + f->state_transition[i] = + get_symbol(c, state, 1) + c->one_state[i]; + } + + 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; get_rac(c, state); //no chroma = false - f->chroma_h_shift= get_symbol(c, state, 0); - f->chroma_v_shift= get_symbol(c, state, 0); + chroma_h_shift = get_symbol(c, state, 0); + chroma_v_shift = get_symbol(c, state, 0); get_rac(c, state); //transparency plane + + if (f->plane_count) { + if (colorspace != f->colorspace || + bits_per_raw_sample != f->avctx->bits_per_raw_sample || + chroma_h_shift != f->chroma_h_shift || + chroma_v_shift != f->chroma_v_shift) { + 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_h_shift = chroma_h_shift; + f->chroma_v_shift = chroma_v_shift; + f->plane_count= 2; } |