Commit 8000d484 authored by Michael Niedermayer's avatar 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: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent a1f6b05f
...@@ -175,7 +175,7 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){ ...@@ -175,7 +175,7 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){
* *
* @param buf_size size of buf in bits * @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_start=
c->bytestream= buf; c->bytestream= buf;
c->bytestream_end= buf + buf_size; c->bytestream_end= buf + buf_size;
...@@ -188,6 +188,9 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ ...@@ -188,6 +188,9 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
#endif #endif
c->low+= ((*c->bytestream++)<<2) + 2; c->low+= ((*c->bytestream++)<<2) + 2;
c->range= 0x1FE; c->range= 0x1FE;
if ((c->range<<(CABAC_BITS+1)) < c->low)
return AVERROR_INVALIDDATA;
return 0;
} }
#ifdef TEST #ifdef TEST
......
...@@ -51,6 +51,6 @@ typedef struct CABACContext{ ...@@ -51,6 +51,6 @@ typedef struct CABACContext{
}CABACContext; }CABACContext;
void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); 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);
#endif /* AVCODEC_CABAC_H */ #endif /* AVCODEC_CABAC_H */
...@@ -191,7 +191,8 @@ static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) { ...@@ -191,7 +191,8 @@ static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) {
#endif #endif
if ((int) (c->bytestream_end - ptr) < n) if ((int) (c->bytestream_end - ptr) < n)
return NULL; 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; return ptr;
} }
......
...@@ -2026,6 +2026,7 @@ decode_intra_mb: ...@@ -2026,6 +2026,7 @@ decode_intra_mb:
const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] * const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *
h->sps.bit_depth_luma >> 3; h->sps.bit_depth_luma >> 3;
const uint8_t *ptr; const uint8_t *ptr;
int ret;
// We assume these blocks are very rare so we do not optimize it. // 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 // FIXME The two following lines get the bitstream position in the cabac
...@@ -2042,7 +2043,9 @@ decode_intra_mb: ...@@ -2042,7 +2043,9 @@ decode_intra_mb:
sl->intra_pcm_ptr = ptr; sl->intra_pcm_ptr = ptr;
ptr += mb_size; ptr += mb_size;
ff_init_cabac_decoder(&sl->cabac, ptr, sl->cabac.bytestream_end - ptr); ret = ff_init_cabac_decoder(&sl->cabac, ptr, sl->cabac.bytestream_end - ptr);
if (ret < 0)
return ret;
// All blocks are present // All blocks are present
h->cbp_table[mb_xy] = 0xf7ef; h->cbp_table[mb_xy] = 0xf7ef;
......
...@@ -2372,9 +2372,11 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) ...@@ -2372,9 +2372,11 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg)
align_get_bits(&sl->gb); align_get_bits(&sl->gb);
/* init cabac */ /* init cabac */
ff_init_cabac_decoder(&sl->cabac, ret = ff_init_cabac_decoder(&sl->cabac,
sl->gb.buffer + get_bits_count(&sl->gb) / 8, sl->gb.buffer + get_bits_count(&sl->gb) / 8,
(get_bits_left(&sl->gb) + 7) / 8); (get_bits_left(&sl->gb) + 7) / 8);
if (ret < 0)
return ret;
ff_h264_init_cabac_states(h, sl); ff_h264_init_cabac_states(h, sl);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment