From e13a16c079cf8f5c758f5c31fbd72edca2656e54 Mon Sep 17 00:00:00 2001 From: Jonathan Solnit Date: Fri, 1 Sep 2017 17:21:05 -0700 Subject: [PATCH] msm: camera2: cpp: Fix iommu_attach/detach compat_ioctl issue When the Camera application exercises the V4L2 ioctl operations, CPP driver would attempt to the copy user space buffer contents into the internal kernel buffer. If an invalid length of the user space buffer is passed onto the driver, it could trigger buffer overflow condition. Thus, fix this by copying user space buffer contents into kernel space buffer of the driver for further processing, only after checking for proper length of user space buffer. Bug: 64433362 CRs-fixed: 2025367 Change-Id: I85cf4a961884c7bb0d036299b886044aef7baf7c Signed-off-by: Ravi kumar Koyyana Signed-off-by: Paresh Purabhiya Signed-off-by: Jonathan Solnit --- .../platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 23 ++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c index 1dfe7f6abc312..9d7e51c37f486 100644 --- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c +++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c @@ -2288,11 +2288,13 @@ static void msm_cpp_fw_version(struct cpp_device *cpp_dev) msm_cpp_poll(cpp_dev->base, MSM_CPP_MSG_ID_TRAILER); } -static int msm_cpp_validate_input(unsigned int cmd, void *arg, +static int msm_cpp_validate_ioctl_input(unsigned int cmd, void *arg, struct msm_camera_v4l2_ioctl_t **ioctl_ptr) { switch (cmd) { case MSM_SD_SHUTDOWN: + case VIDIOC_MSM_CPP_IOMMU_ATTACH: + case VIDIOC_MSM_CPP_IOMMU_DETACH: break; default: { if (ioctl_ptr == NULL) { @@ -2301,8 +2303,9 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg, } *ioctl_ptr = arg; - if ((*ioctl_ptr == NULL) || - (*ioctl_ptr)->ioctl_ptr == NULL) { + if (((*ioctl_ptr) == NULL) || + ((*ioctl_ptr)->ioctl_ptr == NULL) || + ((*ioctl_ptr)->len == 0)) { pr_err("Error invalid ioctl argument cmd %u", cmd); return -EINVAL; } @@ -2334,7 +2337,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, return -EINVAL; } - rc = msm_cpp_validate_input(cmd, arg, &ioctl_ptr); + rc = msm_cpp_validate_ioctl_input(cmd, arg, &ioctl_ptr); if (rc != 0) { pr_err("input validation failed\n"); return rc; @@ -2799,6 +2802,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, pr_err("%s:%dError iommu_attach_device failed\n", __func__, __LINE__); rc = -EINVAL; + break; } cpp_dev->iommu_state = CPP_IOMMU_STATE_ATTACHED; } else { @@ -2813,10 +2817,17 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd, (cpp_dev->stream_cnt == 0)) { iommu_detach_device(cpp_dev->domain, cpp_dev->iommu_ctx); + if (rc < 0) { + pr_err("%s:%dError iommu detach failed\n", + __func__, __LINE__); + rc = -EINVAL; + break; + } cpp_dev->iommu_state = CPP_IOMMU_STATE_DETACHED; } else { pr_err("%s:%d IOMMMU attach triggered in invalid state\n", __func__, __LINE__); + rc = -EINVAL; } break; } @@ -3422,7 +3433,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file, default: pr_err_ratelimited("%s: unsupported compat type :%x LOAD %lu\n", __func__, cmd, VIDIOC_MSM_CPP_LOAD_FIRMWARE); - break; + return -EINVAL; } switch (cmd) { @@ -3448,7 +3459,7 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file, default: pr_err_ratelimited("%s: unsupported compat type :%d\n", __func__, cmd); - break; + return -EINVAL; } up32_ioctl.id = kp_ioctl.id;