aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorJanne Grunau <janne-libav@jannau.net>2012-12-15 22:21:23 +0100
committerJanne Grunau <janne-libav@jannau.net>2012-12-18 11:01:14 +0100
commit61c6eef5456f2bc8b1dc49a0a759c975551cea29 (patch)
tree33bee5b20a90f39428dcf2eec256cc93323bca53 /libavcodec
parent26e4f0c70f781a16f4234c101ceceb640ec5ff31 (diff)
downloadffmpeg-61c6eef5456f2bc8b1dc49a0a759c975551cea29.tar.gz
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.
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/h264.c27
-rw-r--r--libavcodec/h264.h3
2 files changed, 23 insertions, 7 deletions
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 4146b6f052..f568858792 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -954,7 +954,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)
{
@@ -1001,7 +1002,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;
@@ -1014,7 +1015,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;
@@ -1025,7 +1026,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;
@@ -3708,7 +3709,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;
@@ -3831,6 +3833,17 @@ 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)) {
+ 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;
switch (hx->nal_unit_type) {
case NAL_IDR_SLICE:
@@ -3953,6 +3966,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);
@@ -4049,7 +4064,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 3c99030ed2..30494706a8 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,
};
/**