diff options
author | Mark Thompson <sw@jkqxz.net> | 2018-01-09 23:56:41 +0100 |
---|---|---|
committer | Mark Thompson <sw@jkqxz.net> | 2018-01-21 00:37:35 +0000 |
commit | a0c624e299730c8c5800375c2f5f3c6c200053ff (patch) | |
tree | 6a7b9312d0b25d9a65d160d62165675d4985bdfb /libavcodec/v4l2_m2m_enc.c | |
parent | 6c1c6c6c71fc776c6dd25d13861b036dad2cdc1b (diff) | |
download | ffmpeg-a0c624e299730c8c5800375c2f5f3c6c200053ff.tar.gz |
avcodec: v4l2_m2m: fix races around freeing data on close
Refcount all of the context information. This also fixes a potential
segmentation fault when accessing freed memory (buffer returned after
the codec has been closed).
Tested-by: Jorge Ramirez-Ortiz <jorge.ramirez.ortiz@gmail.com>
Diffstat (limited to 'libavcodec/v4l2_m2m_enc.c')
-rw-r--r-- | libavcodec/v4l2_m2m_enc.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/libavcodec/v4l2_m2m_enc.c b/libavcodec/v4l2_m2m_enc.c index 7e88f4d2e6..4c9ea1fd92 100644 --- a/libavcodec/v4l2_m2m_enc.c +++ b/libavcodec/v4l2_m2m_enc.c @@ -242,7 +242,7 @@ static int v4l2_prepare_encoder(V4L2m2mContext *s) static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame) { - V4L2m2mContext *s = avctx->priv_data; + V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const output = &s->output; return ff_v4l2_context_enqueue_frame(output, frame); @@ -250,7 +250,7 @@ static int v4l2_send_frame(AVCodecContext *avctx, const AVFrame *frame) static int v4l2_receive_packet(AVCodecContext *avctx, AVPacket *avpkt) { - V4L2m2mContext *s = avctx->priv_data; + V4L2m2mContext *s = ((V4L2m2mPriv*)avctx->priv_data)->context; V4L2Context *const capture = &s->capture; V4L2Context *const output = &s->output; int ret; @@ -280,11 +280,17 @@ dequeue: static av_cold int v4l2_encode_init(AVCodecContext *avctx) { - V4L2m2mContext *s = avctx->priv_data; - V4L2Context *capture = &s->capture; - V4L2Context *output = &s->output; + V4L2Context *capture, *output; + V4L2m2mContext *s; int ret; + ret = ff_v4l2_m2m_create_context(avctx, &s); + if (ret < 0) + return ret; + + capture = &s->capture; + output = &s->output; + /* common settings output/capture */ output->height = capture->height = avctx->height; output->width = capture->width = avctx->width; @@ -306,13 +312,13 @@ static av_cold int v4l2_encode_init(AVCodecContext *avctx) return v4l2_prepare_encoder(s); } -#define OFFSET(x) offsetof(V4L2m2mContext, x) +#define OFFSET(x) offsetof(V4L2m2mPriv, x) #define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { V4L_M2M_DEFAULT_OPTS, { "num_capture_buffers", "Number of buffers in the capture context", - OFFSET(capture.num_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS }, + OFFSET(num_capture_buffers), AV_OPT_TYPE_INT, {.i64 = 4 }, 4, INT_MAX, FLAGS }, { NULL }, }; @@ -329,7 +335,7 @@ AVCodec ff_ ## NAME ## _v4l2m2m_encoder = { \ .long_name = NULL_IF_CONFIG_SMALL("V4L2 mem2mem " LONGNAME " encoder wrapper"),\ .type = AVMEDIA_TYPE_VIDEO,\ .id = CODEC ,\ - .priv_data_size = sizeof(V4L2m2mContext),\ + .priv_data_size = sizeof(V4L2m2mPriv),\ .priv_class = &v4l2_m2m_ ## NAME ##_enc_class,\ .init = v4l2_encode_init,\ .send_frame = v4l2_send_frame,\ |