From 5f3b68da4c8f6474df2497b6d912465d640904b8 Mon Sep 17 00:00:00 2001 From: Ravi kumar Koyyana Date: Tue, 11 Apr 2017 18:47:44 -0700 Subject: msm: camera2: cpp: Fix out-of-bounds frame or command buffer access When user application provides invalid (out of range) stripe size and stripe indices, while submitting requests for the stripe based image processing by the CPP kernel driver, the driver could perform out of bounds access of the internal buffers. This fix ensures that stripe size and indices of frame/command buffer are properly validated during the configuration and before processing such requests through the CPP hardware block. CRs-fixed: 2002207 Change-Id: Ib79e36fb507d8e75d8fc28afb990020a0e1bf845 Signed-off-by: Ravi kumar Koyyana --- .../platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 33 ++++++++++++++++++---- 1 file changed, 27 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 79a8e8e..8269dc7 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 @@ -2281,9 +2281,29 @@ static int msm_cpp_cfg_frame(struct cpp_device *cpp_dev, return -EINVAL; } - if (stripe_base == UINT_MAX || new_frame->num_strips > - (UINT_MAX - 1 - stripe_base) / stripe_size) { - pr_err("Invalid frame message,num_strips %d is large\n", + /* Stripe index starts at zero */ + if ((!new_frame->num_strips) || + (new_frame->first_stripe_index >= new_frame->num_strips) || + (new_frame->last_stripe_index >= new_frame->num_strips) || + (new_frame->first_stripe_index > + new_frame->last_stripe_index)) { + pr_err("Invalid frame message, #stripes=%d, stripe indices=[%d,%d]\n", + new_frame->num_strips, + new_frame->first_stripe_index, + new_frame->last_stripe_index); + return -EINVAL; + } + + if (!stripe_size) { + pr_err("Invalid frame message, invalid stripe_size (%d)!\n", + stripe_size); + return -EINVAL; + } + + if ((stripe_base == UINT_MAX) || + (new_frame->num_strips > + (UINT_MAX - 1 - stripe_base) / stripe_size)) { + pr_err("Invalid frame message, num_strips %d is large\n", new_frame->num_strips); return -EINVAL; } @@ -2523,13 +2543,14 @@ static int msm_cpp_cfg(struct cpp_device *cpp_dev, struct msm_cpp_frame_info_t *frame = NULL; struct msm_cpp_frame_info_t k_frame_info; int32_t rc = 0; - int32_t i = 0; - int32_t num_buff = sizeof(k_frame_info.output_buffer_info)/ + uint32_t i = 0; + uint32_t num_buff = sizeof(k_frame_info.output_buffer_info) / sizeof(struct msm_cpp_buffer_info_t); + if (copy_from_user(&k_frame_info, (void __user *)ioctl_ptr->ioctl_ptr, sizeof(k_frame_info))) - return -EFAULT; + return -EFAULT; frame = msm_cpp_get_frame(ioctl_ptr); if (!frame) { -- cgit v1.1