summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay kumar Tumati <vtumati@codeaurora.org>2019-04-16 15:37:42 +0530
committerGerrit - the friendly Code Review server <code-review@localhost>2019-05-15 22:04:10 -0700
commitb79e25fe5818f14e3bb77f15d0930f773d61ae72 (patch)
tree0879281d15df06e65cf4c999e04de6d3a6b29222
parent592adc48492083ee94921e48da73473888949561 (diff)
msm: camera : Lock Implementation for avoid race condition
Lock Implementation for avoid race condition leading to out-of-bound write in "msm_vb2_queue_setup CRs-Fixed: 2362627 Change-Id: I7f7420c7437b9ac2f215929a8614b0846e890c98 Signed-off-by: Vijay kumar Tumati <vtumati@codeaurora.org> Signed-off-by: Haibin Liu <haibinl@codeaurora.org>
-rw-r--r--drivers/media/platform/msm/camera_v2/camera/camera.c35
-rw-r--r--drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c20
2 files changed, 38 insertions, 17 deletions
diff --git a/drivers/media/platform/msm/camera_v2/camera/camera.c b/drivers/media/platform/msm/camera_v2/camera/camera.c
index ccdd4622c120..1c721e95180a 100644
--- a/drivers/media/platform/msm/camera_v2/camera/camera.c
+++ b/drivers/media/platform/msm/camera_v2/camera/camera.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2017, 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
@@ -366,9 +366,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));
user_fmt = (struct msm_v4l2_format_data *)sp->vb2_q.drv_priv;
@@ -377,27 +380,29 @@ static int camera_v4l2_s_fmt_vid_cap_mplane(struct file *filep, void *fh,
user_fmt->num_planes);
/*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;
}
@@ -597,6 +602,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();
@@ -616,6 +627,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/camera_v2/msm_vb2/msm_vb2.c b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
index f2b048e37319..5943d57812f0 100644
--- a/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.c
+++ b/drivers/media/platform/msm/camera_v2/msm_vb2/msm_vb2.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
@@ -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,13 @@ 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;
+ rc = 0;
+
+done:
+ mutex_unlock(q->lock);
+ return rc;
}
int msm_vb2_buf_init(struct vb2_buffer *vb)