It is not posible to call get_buffer during frame-mt codec initialization. Libavformat might pass huge amounts of data as extradata after parsing broken files. The 'extradata' for the fuzzed sample sample_varPAR_s5374_r001-02.avi is 2.8M large and contains multiple slices. --- libavcodec/h264.c | 25 +++++++++++++++++++------ libavcodec/h264.h | 3 ++- 2 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c index a38d9a3..602640b 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -959,7 +959,8 @@ fail: return -1; // free_tables will clean up for us } -static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size); +static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, + int parse_extradata); static av_cold void common_init(H264Context *h) { @@ -1006,7 +1007,7 @@ int ff_h264_decode_extradata(H264Context *h) nalsize = AV_RB16(p) + 2; if (p - avctx->extradata + nalsize > avctx->extradata_size) return -1; - if (decode_nal_units(h, p, nalsize) < 0) { + if (decode_nal_units(h, p, nalsize, 1) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding sps %d from avcC failed\n", i); return -1; @@ -1019,7 +1020,7 @@ int ff_h264_decode_extradata(H264Context *h) nalsize = AV_RB16(p) + 2; if (p - avctx->extradata + nalsize > avctx->extradata_size) return -1; - if (decode_nal_units(h, p, nalsize) < 0) { + if (decode_nal_units(h, p, nalsize, 1) < 0) { av_log(avctx, AV_LOG_ERROR, "Decoding pps %d from avcC failed\n", i); return -1; @@ -1030,7 +1031,7 @@ int ff_h264_decode_extradata(H264Context *h) h->nal_length_size = (avctx->extradata[4] & 0x03) + 1; } else { h->is_avc = 0; - if (decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0) + if (decode_nal_units(h, avctx->extradata, avctx->extradata_size, 1) < 0) return -1; } return 0; @@ -3824,7 +3825,8 @@ static int execute_decode_slices(H264Context *h, int context_count) return 0; } -static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) +static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, + int parse_extradata) { MpegEncContext *const s = &h->s; AVCodecContext *const avctx = s->avctx; @@ -3947,6 +3949,15 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) continue; again: + /* Ignore every NAL unit type except PPS and SPS during extradata + * parsing. Decoding slices is not possible in codec init + * with frame-mt */ + if (parse_extradata && HAVE_THREADS && + (s->avctx->active_thread_type & FF_THREAD_FRAME) && + (hx->nal_unit_type != NAL_PPS && + hx->nal_unit_type != NAL_SPS)) + hx->nal_unit_type = NAL_FF_IGNORE; + err = 0; switch (hx->nal_unit_type) { case NAL_IDR_SLICE: @@ -4069,6 +4080,8 @@ again: case NAL_SPS_EXT: case NAL_AUXILIARY_SLICE: break; + case NAL_FF_IGNORE: + break; default: av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", hx->nal_unit_type, bit_length); @@ -4165,7 +4178,7 @@ out: return buf_index; } - buf_index = decode_nal_units(h, buf, buf_size); + buf_index = decode_nal_units(h, buf, buf_size, 0); if (buf_index < 0) return -1; diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 7d19c1f..8596121 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -112,7 +112,8 @@ enum { NAL_END_STREAM, NAL_FILLER_DATA, NAL_SPS_EXT, - NAL_AUXILIARY_SLICE = 19 + NAL_AUXILIARY_SLICE = 19, + NAL_FF_IGNORE = 0xff0f001, }; /** -- 1.7.12.4 _______________________________________________ libav-devel mailing list libav-devel@libav.org https://lists.libav.org/mailman/listinfo/libav-devel