Commit 61c6eef5 authored by Janne Grunau's avatar Janne Grunau

h264: prevent decoding of slice NALs in extradata

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.
parent 26e4f0c7
...@@ -954,7 +954,8 @@ fail: ...@@ -954,7 +954,8 @@ fail:
return -1; // free_tables will clean up for us 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) static av_cold void common_init(H264Context *h)
{ {
...@@ -1001,7 +1002,7 @@ int ff_h264_decode_extradata(H264Context *h) ...@@ -1001,7 +1002,7 @@ int ff_h264_decode_extradata(H264Context *h)
nalsize = AV_RB16(p) + 2; nalsize = AV_RB16(p) + 2;
if (p - avctx->extradata + nalsize > avctx->extradata_size) if (p - avctx->extradata + nalsize > avctx->extradata_size)
return -1; 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, av_log(avctx, AV_LOG_ERROR,
"Decoding sps %d from avcC failed\n", i); "Decoding sps %d from avcC failed\n", i);
return -1; return -1;
...@@ -1014,7 +1015,7 @@ int ff_h264_decode_extradata(H264Context *h) ...@@ -1014,7 +1015,7 @@ int ff_h264_decode_extradata(H264Context *h)
nalsize = AV_RB16(p) + 2; nalsize = AV_RB16(p) + 2;
if (p - avctx->extradata + nalsize > avctx->extradata_size) if (p - avctx->extradata + nalsize > avctx->extradata_size)
return -1; 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, av_log(avctx, AV_LOG_ERROR,
"Decoding pps %d from avcC failed\n", i); "Decoding pps %d from avcC failed\n", i);
return -1; return -1;
...@@ -1025,7 +1026,7 @@ int ff_h264_decode_extradata(H264Context *h) ...@@ -1025,7 +1026,7 @@ int ff_h264_decode_extradata(H264Context *h)
h->nal_length_size = (avctx->extradata[4] & 0x03) + 1; h->nal_length_size = (avctx->extradata[4] & 0x03) + 1;
} else { } else {
h->is_avc = 0; 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 -1;
} }
return 0; return 0;
...@@ -3708,7 +3709,8 @@ static int execute_decode_slices(H264Context *h, int context_count) ...@@ -3708,7 +3709,8 @@ static int execute_decode_slices(H264Context *h, int context_count)
return 0; 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; MpegEncContext *const s = &h->s;
AVCodecContext *const avctx = s->avctx; AVCodecContext *const avctx = s->avctx;
...@@ -3831,6 +3833,17 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) ...@@ -3831,6 +3833,17 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size)
continue; continue;
again: 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)) {
av_log(avctx, AV_LOG_INFO, "Ignoring NAL unit %d during "
"extradata parsing\n", hx->nal_unit_type);
hx->nal_unit_type = NAL_FF_IGNORE;
}
err = 0; err = 0;
switch (hx->nal_unit_type) { switch (hx->nal_unit_type) {
case NAL_IDR_SLICE: case NAL_IDR_SLICE:
...@@ -3953,6 +3966,8 @@ again: ...@@ -3953,6 +3966,8 @@ again:
case NAL_SPS_EXT: case NAL_SPS_EXT:
case NAL_AUXILIARY_SLICE: case NAL_AUXILIARY_SLICE:
break; break;
case NAL_FF_IGNORE:
break;
default: default:
av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n", av_log(avctx, AV_LOG_DEBUG, "Unknown NAL code: %d (%d bits)\n",
hx->nal_unit_type, bit_length); hx->nal_unit_type, bit_length);
...@@ -4049,7 +4064,7 @@ out: ...@@ -4049,7 +4064,7 @@ out:
return buf_index; 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) if (buf_index < 0)
return -1; return -1;
......
...@@ -112,7 +112,8 @@ enum { ...@@ -112,7 +112,8 @@ enum {
NAL_END_STREAM, NAL_END_STREAM,
NAL_FILLER_DATA, NAL_FILLER_DATA,
NAL_SPS_EXT, NAL_SPS_EXT,
NAL_AUXILIARY_SLICE = 19 NAL_AUXILIARY_SLICE = 19,
NAL_FF_IGNORE = 0xff0f001,
}; };
/** /**
......
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