mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-30 01:46:30 -05:00
147 lines
5.5 KiB
Diff
147 lines
5.5 KiB
Diff
|
From f615e40c706708f74cd826d5b19c63025f54c041 Mon Sep 17 00:00:00 2001
|
||
|
From: Seemanta Dutta <seemanta@codeaurora.org>
|
||
|
Date: Tue, 23 Jul 2013 15:52:22 -0700
|
||
|
Subject: msm: camera: Fix potential memory overflow errors
|
||
|
|
||
|
Fix potential memory overflow errors in msm_isp_util.c which happen
|
||
|
under certain rare conditions.
|
||
|
|
||
|
CRs-fixed: 514717
|
||
|
Change-Id: I8c70e089df9bf1e7a364c5c8264b782c9c23bf0b
|
||
|
Signed-off-by: Seemanta Dutta <seemanta@codeaurora.org>
|
||
|
---
|
||
|
.../platform/msm/camera_v2/isp/msm_isp_util.c | 47 +++++++++++++++++++---
|
||
|
.../platform/msm/camera_v2/isp/msm_isp_util.h | 2 +-
|
||
|
2 files changed, 43 insertions(+), 6 deletions(-)
|
||
|
|
||
|
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||
|
index 3806213..9b9c5a3 100644
|
||
|
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||
|
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||
|
@@ -366,7 +366,7 @@ long msm_isp_ioctl(struct v4l2_subdev *sd,
|
||
|
break;
|
||
|
case VIDIOC_MSM_ISP_SET_SRC_STATE:
|
||
|
mutex_lock(&vfe_dev->core_mutex);
|
||
|
- msm_isp_set_src_state(vfe_dev, arg);
|
||
|
+ rc = msm_isp_set_src_state(vfe_dev, arg);
|
||
|
mutex_unlock(&vfe_dev->core_mutex);
|
||
|
break;
|
||
|
case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
|
||
|
@@ -410,7 +410,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
if (resource_size(vfe_dev->vfe_mem) <
|
||
|
(reg_cfg_cmd->u.rw_info.reg_offset +
|
||
|
reg_cfg_cmd->u.rw_info.len)) {
|
||
|
- pr_err("%s: Invalid length\n", __func__);
|
||
|
+ pr_err("%s: VFE_WRITE: Invalid length\n", __func__);
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
msm_camera_io_memcpy(vfe_dev->vfe_base +
|
||
|
@@ -422,16 +422,37 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
case VFE_WRITE_MB: {
|
||
|
uint32_t *data_ptr = cfg_data +
|
||
|
reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
|
||
|
+
|
||
|
+ if ((UINT_MAX - sizeof(*data_ptr) <
|
||
|
+ reg_cfg_cmd->u.rw_info.reg_offset) ||
|
||
|
+ (resource_size(vfe_dev->vfe_mem) <
|
||
|
+ reg_cfg_cmd->u.rw_info.reg_offset +
|
||
|
+ sizeof(*data_ptr))) {
|
||
|
+ pr_err("%s: VFE_WRITE_MB: Invalid length\n", __func__);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
msm_camera_io_w_mb(*data_ptr, vfe_dev->vfe_base +
|
||
|
reg_cfg_cmd->u.rw_info.reg_offset);
|
||
|
break;
|
||
|
}
|
||
|
case VFE_CFG_MASK: {
|
||
|
uint32_t temp;
|
||
|
+ if (resource_size(vfe_dev->vfe_mem) <
|
||
|
+ reg_cfg_cmd->u.mask_info.reg_offset)
|
||
|
+ return -EINVAL;
|
||
|
temp = msm_camera_io_r(vfe_dev->vfe_base +
|
||
|
reg_cfg_cmd->u.mask_info.reg_offset);
|
||
|
+
|
||
|
temp &= ~reg_cfg_cmd->u.mask_info.mask;
|
||
|
temp |= reg_cfg_cmd->u.mask_info.val;
|
||
|
+ if ((UINT_MAX - sizeof(temp) <
|
||
|
+ reg_cfg_cmd->u.mask_info.reg_offset) ||
|
||
|
+ (resource_size(vfe_dev->vfe_mem) <
|
||
|
+ reg_cfg_cmd->u.mask_info.reg_offset +
|
||
|
+ sizeof(temp))) {
|
||
|
+ pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
msm_camera_io_w(temp, vfe_dev->vfe_base +
|
||
|
reg_cfg_cmd->u.mask_info.reg_offset);
|
||
|
break;
|
||
|
@@ -443,8 +464,10 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
|
||
|
uint32_t hi_val, lo_val, lo_val1;
|
||
|
if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
|
||
|
- if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||
|
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||
|
+ if ((UINT_MAX - reg_cfg_cmd->u.dmi_info.hi_tbl_offset <
|
||
|
+ reg_cfg_cmd->u.dmi_info.len) ||
|
||
|
+ (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||
|
+ reg_cfg_cmd->u.dmi_info.len > cmd_len)) {
|
||
|
pr_err("Invalid Hi Table out of bounds\n");
|
||
|
return -EINVAL;
|
||
|
}
|
||
|
@@ -528,6 +551,12 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
uint32_t *data_ptr = cfg_data +
|
||
|
reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
|
||
|
for (i = 0; i < reg_cfg_cmd->u.rw_info.len/4; i++) {
|
||
|
+ if ((data_ptr < cfg_data) ||
|
||
|
+ (UINT_MAX / sizeof(*data_ptr) <
|
||
|
+ (data_ptr - cfg_data)) ||
|
||
|
+ (sizeof(*data_ptr) * (data_ptr - cfg_data) >
|
||
|
+ cmd_len))
|
||
|
+ return -EINVAL;
|
||
|
*data_ptr++ = msm_camera_io_r(vfe_dev->vfe_base +
|
||
|
reg_cfg_cmd->u.rw_info.reg_offset);
|
||
|
reg_cfg_cmd->u.rw_info.reg_offset += 4;
|
||
|
@@ -545,6 +574,11 @@ int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg)
|
||
|
struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd;
|
||
|
uint32_t *cfg_data;
|
||
|
|
||
|
+ if (!proc_cmd->num_cfg) {
|
||
|
+ pr_err("%s: Passed num_cfg as 0\n", __func__);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+
|
||
|
reg_cfg_cmd = kzalloc(sizeof(struct msm_vfe_reg_cfg_cmd)*
|
||
|
proc_cmd->num_cfg, GFP_KERNEL);
|
||
|
if (!reg_cfg_cmd) {
|
||
|
@@ -856,11 +890,14 @@ void msm_isp_do_tasklet(unsigned long data)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
-void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
|
||
|
+int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
|
||
|
{
|
||
|
struct msm_vfe_axi_src_state *src_state = arg;
|
||
|
+ if (src_state->input_src >= VFE_SRC_MAX)
|
||
|
+ return -EINVAL;
|
||
|
vfe_dev->axi_data.src_info[src_state->input_src].active =
|
||
|
src_state->src_active;
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||
|
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
|
||
|
index 34b9859..9d9558a 100644
|
||
|
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
|
||
|
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
|
||
|
@@ -64,7 +64,7 @@ int msm_isp_cal_word_per_line(uint32_t output_format,
|
||
|
uint32_t pixel_per_line);
|
||
|
int msm_isp_get_bit_per_pixel(uint32_t output_format);
|
||
|
irqreturn_t msm_isp_process_irq(int irq_num, void *data);
|
||
|
-void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg);
|
||
|
+int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg);
|
||
|
void msm_isp_do_tasklet(unsigned long data);
|
||
|
void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev);
|
||
|
void msm_isp_process_error_info(struct vfe_device *vfe_dev);
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|