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@niedermayer.cc> (cherry picked from commit 8000d484b83aafa752d84fbdbfb352ffe0dc64f8) Conflicts: libavcodec/cabac.h Conflicts: libavcodec/h264_cabac.c libavcodec/h264_slice.c
This commit is contained in:
parent
2da8c53386
commit
1f6aea2cc4
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -2000,6 +2000,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
|
||||||
@ -2016,7 +2017,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;
|
||||||
|
@ -2422,13 +2422,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);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user