diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2012-01-26 15:41:43 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2012-01-26 17:05:57 +0100 |
commit | e2291ea1534d17306f685b8c8abc8585bbed87bf (patch) | |
tree | 13c1478094703457599a3f37c976cc7544a072da /libavcodec/diracdec.c | |
parent | ee0cab7721cc31e5d8027ec7df6c3ebd60ea50b5 (diff) | |
download | ffmpeg-streaming-e2291ea1534d17306f685b8c8abc8585bbed87bf.zip ffmpeg-streaming-e2291ea1534d17306f685b8c8abc8585bbed87bf.tar.gz |
diracdec: Check dirac_unpack_idwt_params parameters before storing them.
Fixes CVE-2011-3949
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/diracdec.c')
-rw-r--r-- | libavcodec/diracdec.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 1bc7334..e6b33e2 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -933,6 +933,15 @@ static int dirac_unpack_idwt_params(DiracContext *s) { GetBitContext *gb = &s->gb; int i, level; + unsigned tmp; + +#define CHECKEDREAD(dst, cond, errmsg) \ + tmp = svq3_get_ue_golomb(gb); \ + if (cond) { \ + av_log(s->avctx, AV_LOG_ERROR, errmsg); \ + return -1; \ + }\ + dst = tmp; align_get_bits(gb); @@ -941,29 +950,19 @@ static int dirac_unpack_idwt_params(DiracContext *s) return 0; /*[DIRAC_STD] 11.3.1 Transform parameters. transform_parameters() */ - s->wavelet_idx = svq3_get_ue_golomb(gb); - if (s->wavelet_idx > 6) - return -1; + CHECKEDREAD(s->wavelet_idx, tmp > 6, "wavelet_idx is too big\n") - s->wavelet_depth = svq3_get_ue_golomb(gb); - if (s->wavelet_depth > MAX_DWT_LEVELS) { - av_log(s->avctx, AV_LOG_ERROR, "too many dwt decompositions\n"); - return -1; - } + CHECKEDREAD(s->wavelet_depth, tmp > MAX_DWT_LEVELS || tmp < 1, "invalid number of DWT decompositions\n") if (!s->low_delay) { /* Codeblock paramaters (core syntax only) */ if (get_bits1(gb)) { for (i = 0; i <= s->wavelet_depth; i++) { - s->codeblock[i].width = svq3_get_ue_golomb(gb); - s->codeblock[i].height = svq3_get_ue_golomb(gb); + CHECKEDREAD(s->codeblock[i].width , tmp < 1, "codeblock width invalid\n") + CHECKEDREAD(s->codeblock[i].height, tmp < 1, "codeblock height invalid\n") } - s->codeblock_mode = svq3_get_ue_golomb(gb); - if (s->codeblock_mode > 1) { - av_log(s->avctx, AV_LOG_ERROR, "unknown codeblock mode\n"); - return -1; - } + CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n") } else for (i = 0; i <= s->wavelet_depth; i++) s->codeblock[i].width = s->codeblock[i].height = 1; |