Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FFmpeg/FFmpeg.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/APIchanges6
-rw-r--r--libavcodec/utils.c26
-rw-r--r--libavcodec/version.h2
-rw-r--r--libavutil/frame.h3
4 files changed, 36 insertions, 1 deletions
diff --git a/doc/APIchanges b/doc/APIchanges
index a808e9e794..a75f3468f1 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -15,6 +15,12 @@ libavutil: 2015-08-28
API changes, most recent first:
+2016-02-28 - xxxxxxx - lavc 57.27.101
+ Validate AVFrame returned by get_buffer2 to have required
+ planes not NULL and unused planes set to NULL as crashes
+ and buffer overflow are possible with certain streams if
+ that is not the case.
+
2016-xx-xx - xxxxxxx - lavc 57.27.100 - avcodec.h
"flags2" decoding option now allows the flag "ass_ro_flush_noop" preventing
the reset of the ASS ReadOrder field on flush. This affects the content of
diff --git a/libavcodec/utils.c b/libavcodec/utils.c
index 5791ffaef6..b1ba51e797 100644
--- a/libavcodec/utils.c
+++ b/libavcodec/utils.c
@@ -853,6 +853,30 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame)
return ff_init_buffer_info(avctx, frame);
}
+static void validate_avframe_allocation(AVCodecContext *avctx, AVFrame *frame)
+{
+ if (avctx->codec_type == AVMEDIA_TYPE_VIDEO) {
+ int i;
+ int num_planes = av_pix_fmt_count_planes(frame->format);
+ const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
+ int flags = desc ? desc->flags : 0;
+ if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PAL))
+ num_planes = 2;
+ for (i = 0; i < num_planes; i++) {
+ av_assert0(frame->data[i]);
+ }
+ // For now do not enforce anything for palette of pseudopal formats
+ if (num_planes == 1 && (flags & AV_PIX_FMT_FLAG_PSEUDOPAL))
+ num_planes = 2;
+ // For formats without data like hwaccel allow unused pointers to be non-NULL.
+ for (i = num_planes; num_planes > 0 && i < FF_ARRAY_ELEMS(frame->data); i++) {
+ if (frame->data[i])
+ av_log(avctx, AV_LOG_ERROR, "Buffer returned by get_buffer2() did not zero unused plane pointers\n");
+ frame->data[i] = NULL;
+ }
+ }
+}
+
static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
{
const AVHWAccel *hwaccel = avctx->hwaccel;
@@ -889,6 +913,8 @@ static int get_buffer_internal(AVCodecContext *avctx, AVFrame *frame, int flags)
avctx->sw_pix_fmt = avctx->pix_fmt;
ret = avctx->get_buffer2(avctx, frame, flags);
+ if (ret >= 0)
+ validate_avframe_allocation(avctx, frame);
end:
if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && !override_dimensions) {
diff --git a/libavcodec/version.h b/libavcodec/version.h
index 10a10a7e56..95f4551992 100644
--- a/libavcodec/version.h
+++ b/libavcodec/version.h
@@ -29,7 +29,7 @@
#define LIBAVCODEC_VERSION_MAJOR 57
#define LIBAVCODEC_VERSION_MINOR 27
-#define LIBAVCODEC_VERSION_MICRO 100
+#define LIBAVCODEC_VERSION_MICRO 101
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
LIBAVCODEC_VERSION_MINOR, \
diff --git a/libavutil/frame.h b/libavutil/frame.h
index 56001a8798..76a8123dcb 100644
--- a/libavutil/frame.h
+++ b/libavutil/frame.h
@@ -187,6 +187,9 @@ typedef struct AVFrame {
* see avcodec_align_dimensions2(). Some filters and swscale can read
* up to 16 bytes beyond the planes, if these filters are to be used,
* then 16 extra bytes must be allocated.
+ *
+ * NOTE: Except for hwaccel formats, pointers not needed by the format
+ * MUST be set to NULL.
*/
uint8_t *data[AV_NUM_DATA_POINTERS];