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@niedermayer.cc>
(cherry picked from commit 8000d484b8)
Conflicts:
libavcodec/cabac.h
Conflicts:
libavcodec/h264_cabac.c
libavcodec/h264_slice.c
tags/n2.4.12
| @@ -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 | * @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; | ||||
| @@ -64,6 +64,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; | |||||
| } | } | ||||
| void ff_init_cabac_states(void) | void ff_init_cabac_states(void) | ||||
| @@ -56,7 +56,7 @@ 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); | |||||
| void ff_init_cabac_states(void); | void ff_init_cabac_states(void); | ||||
| #endif /* AVCODEC_CABAC_H */ | #endif /* AVCODEC_CABAC_H */ | ||||
| @@ -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; | ||||
| } | } | ||||
| @@ -1999,6 +1999,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 | ||||
| @@ -2015,7 +2016,9 @@ decode_intra_mb: | |||||
| h->intra_pcm_ptr = ptr; | h->intra_pcm_ptr = ptr; | ||||
| ptr += mb_size; | 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 | // All blocks are present | ||||
| h->cbp_table[mb_xy] = 0xf7ef; | h->cbp_table[mb_xy] = 0xf7ef; | ||||
| @@ -2445,13 +2445,16 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) | |||||
| } | } | ||||
| if (h->pps.cabac) { | if (h->pps.cabac) { | ||||
| int ret; | |||||
| /* realign */ | /* realign */ | ||||
| align_get_bits(&h->gb); | align_get_bits(&h->gb); | ||||
| /* init cabac */ | /* init cabac */ | ||||
| ff_init_cabac_decoder(&h->cabac, | |||||
| ret = ff_init_cabac_decoder(&h->cabac, | |||||
| h->gb.buffer + get_bits_count(&h->gb) / 8, | h->gb.buffer + get_bits_count(&h->gb) / 8, | ||||
| (get_bits_left(&h->gb) + 7) / 8); | (get_bits_left(&h->gb) + 7) / 8); | ||||
| if (ret < 0) | |||||
| return ret; | |||||
| ff_h264_init_cabac_states(h); | ff_h264_init_cabac_states(h); | ||||