From 17fe44d6eb8a27698a417bcc021ee60981e177dc Mon Sep 17 00:00:00 2001 From: E V Ravi Date: Thu, 16 May 2019 14:51:01 +0530 Subject: [PATCH] msm: ais : Lock Implementation for avoid race condition Lock Implementation for avoid race condition leading to out-of-bound write in "msm_vb2_queue_setup Change-Id: I386f1709bdf3328ae0c1db44980db8453849babf Signed-off-by: E V Ravi --- .../media/platform/msm/ais/camera/camera.c | 33 ++++++++++++++----- .../media/platform/msm/ais/msm_vb2/msm_vb2.c | 18 ++++++---- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/drivers/media/platform/msm/ais/camera/camera.c b/drivers/media/platform/msm/ais/camera/camera.c index 353b74794bc8..dafd4be11bba 100644 --- a/drivers/media/platform/msm/ais/camera/camera.c +++ b/drivers/media/platform/msm/ais/camera/camera.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -370,8 +370,12 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, if (pfmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { - if (WARN_ON(!sp->vb2_q.drv_priv)) - return -ENOMEM; + mutex_lock(sp->vb2_q.lock); + if (WARN_ON(!sp->vb2_q.drv_priv)) { + rc = -ENOMEM; + mutex_unlock(sp->vb2_q.lock); + goto done; + } memcpy(sp->vb2_q.drv_priv, pfmt->fmt.raw_data, sizeof(struct msm_v4l2_format_data)); @@ -382,27 +386,30 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh, /* num_planes need to bound checked, otherwise for loop * can execute forever */ - if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) - return -EINVAL; + if (WARN_ON(user_fmt->num_planes > VIDEO_MAX_PLANES)) { + rc = -EINVAL; + mutex_unlock(sp->vb2_q.lock); + goto done; + } for (i = 0; i < user_fmt->num_planes; i++) pr_debug("%s: plane size[%d]\n", __func__, user_fmt->plane_sizes[i]); - + mutex_unlock(sp->vb2_q.lock); if (msm_is_daemon_present() != false) { camera_pack_event(filep, MSM_CAMERA_SET_PARM, MSM_CAMERA_PRIV_S_FMT, -1, &event); rc = msm_post_event(&event, MSM_POST_EVT_TIMEOUT); if (rc < 0) - return rc; + goto done; rc = camera_check_event_status(&event); if (rc < 0) - return rc; + goto done; } sp->is_vb2_valid = 1; } - +done: return rc; } @@ -600,6 +607,12 @@ static int camera_v4l2_vb2_q_init(struct file *filep) pr_err("%s : memory not available\n", __func__); return -ENOMEM; } + q->lock = kzalloc(sizeof(struct mutex), GFP_KERNEL); + if (!q->lock) { + kzfree(q->drv_priv); + return -ENOMEM; + } + mutex_init(q->lock); q->mem_ops = msm_vb2_get_q_mem_ops(); q->ops = msm_vb2_get_q_ops(); @@ -619,6 +632,8 @@ static void camera_v4l2_vb2_q_release(struct file *filep) kzfree(sp->vb2_q.drv_priv); mutex_lock(&sp->lock); vb2_queue_release(&sp->vb2_q); + mutex_destroy(sp->vb2_q.lock); + kzfree(sp->vb2_q.lock); mutex_unlock(&sp->lock); } diff --git a/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c index 1cbc49c8485c..4fe40a5b34bd 100644 --- a/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c +++ b/drivers/media/platform/msm/ais/msm_vb2/msm_vb2.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. +/* Copyright (c) 2012-2017, 2019 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and @@ -19,15 +19,19 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, unsigned int sizes[], void *alloc_ctxs[]) { int i; - struct msm_v4l2_format_data *data = q->drv_priv; + struct msm_v4l2_format_data *data = NULL; + int rc = -EINVAL; + + mutex_lock(q->lock); + data = q->drv_priv; if (!data) { pr_err("%s: drv_priv NULL\n", __func__); - return -EINVAL; + goto done; } if (data->type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) { if (WARN_ON(data->num_planes > VIDEO_MAX_PLANES)) - return -EINVAL; + goto done; *num_planes = data->num_planes; @@ -36,9 +40,11 @@ static int msm_vb2_queue_setup(struct vb2_queue *q, } else { pr_err("%s: Unsupported buf type :%d\n", __func__, data->type); - return -EINVAL; + goto done; } - return 0; +done: + mutex_unlock(q->lock); + return rc; } static int msm_vb2_buf_init(struct vb2_buffer *vb)