[FFmpeg-cvslog] avcodec/cabac: Check initial cabac decoder state
Michael Niedermayer
git at videolan.org
Sun Dec 20 14:06:25 CET 2015
ffmpeg | branch: release/2.6 | Michael Niedermayer <michael at niedermayer.cc> | Fri Nov 27 13:37:50 2015 +0100| [1f6aea2cc4e379346d0b5b67e9ce775e12b39def] | committer: Michael Niedermayer
avcodec/cabac: Check initial cabac decoder state
Fixes integer overflows
Fixes: 1430e9c43fae47a24c179c7c54f94918/signal_sigsegv_421427_2340_591e9810c7b09efe501ad84638c9e9f8.264
Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Found-by: xiedingbao (Ticket4727)
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
(cherry picked from commit 8000d484b83aafa752d84fbdbfb352ffe0dc64f8)
Conflicts:
libavcodec/cabac.h
Conflicts:
libavcodec/h264_cabac.c
libavcodec/h264_slice.c
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=1f6aea2cc4e379346d0b5b67e9ce775e12b39def
---
libavcodec/cabac.c | 5 ++++-
libavcodec/cabac.h | 2 +-
libavcodec/cabac_functions.h | 3 ++-
libavcodec/h264_cabac.c | 5 ++++-
libavcodec/h264_slice.c | 5 ++++-
5 files changed, 15 insertions(+), 5 deletions(-)
diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c
index 81a75dd..48f70ca 100644
--- a/libavcodec/cabac.c
+++ b/libavcodec/cabac.c
@@ -51,7 +51,7 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
*
* @param buf_size size of buf in bits
*/
-void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
+int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
c->bytestream_start=
c->bytestream= buf;
c->bytestream_end= buf + buf_size;
@@ -64,6 +64,9 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
#endif
c->low+= ((*c->bytestream++)<<2) + 2;
c->range= 0x1FE;
+ if ((c->range<<(CABAC_BITS+1)) < c->low)
+ return AVERROR_INVALIDDATA;
+ return 0;
}
void ff_init_cabac_states(void)
diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h
index f9eafed..857211c 100644
--- a/libavcodec/cabac.h
+++ b/libavcodec/cabac.h
@@ -56,7 +56,7 @@ typedef struct CABACContext{
}CABACContext;
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
-void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
+int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
void ff_init_cabac_states(void);
#endif /* AVCODEC_CABAC_H */
diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h
index 4e13253..2d1d2a6 100644
--- a/libavcodec/cabac_functions.h
+++ b/libavcodec/cabac_functions.h
@@ -191,7 +191,8 @@ static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) {
#endif
if ((int) (c->bytestream_end - ptr) < n)
return NULL;
- ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n);
+ if (ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n) < 0)
+ return NULL;
return ptr;
}
diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c
index 41e0f86..397b070 100644
--- a/libavcodec/h264_cabac.c
+++ b/libavcodec/h264_cabac.c
@@ -2000,6 +2000,7 @@ decode_intra_mb:
const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
h->sps.bit_depth_luma >> 3;
const uint8_t *ptr;
+ int ret;
// We assume these blocks are very rare so we do not optimize it.
// FIXME The two following lines get the bitstream position in the cabac
@@ -2016,7 +2017,9 @@ decode_intra_mb:
h->intra_pcm_ptr = ptr;
ptr += mb_size;
- ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);
+ ret = ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);
+ if (ret < 0)
+ return ret;
// All blocks are present
h->cbp_table[mb_xy] = 0xf7ef;
diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c
index 3501be3..b0b4060 100644
--- a/libavcodec/h264_slice.c
+++ b/libavcodec/h264_slice.c
@@ -2422,13 +2422,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
}
if (h->pps.cabac) {
+ int ret;
/* realign */
align_get_bits(&h->gb);
/* init cabac */
- ff_init_cabac_decoder(&h->cabac,
+ ret = ff_init_cabac_decoder(&h->cabac,
h->gb.buffer + get_bits_count(&h->gb) / 8,
(get_bits_left(&h->gb) + 7) / 8);
+ if (ret < 0)
+ return ret;
ff_h264_init_cabac_states(h);
More information about the ffmpeg-cvslog
mailing list