mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
256 lines
9.0 KiB
Diff
256 lines
9.0 KiB
Diff
|
From 51c39420e3a49d1a7f05a77c64369b7623088238 Mon Sep 17 00:00:00 2001
|
||
|
From: Sreesudhan Ramakrish Ramkumar <srramku@codeaurora.org>
|
||
|
Date: Fri, 12 Dec 2014 04:20:59 -0800
|
||
|
Subject: msm: camera: isp: Validate input parameter for vfe_write and vfe_read
|
||
|
|
||
|
Validate input parameters for read and write operations in vfe to
|
||
|
ensure operations are performed within vfe register boundary and
|
||
|
within structure limits passed by caller.
|
||
|
|
||
|
Change-Id: If3719de65b32773c2b6ff904da76a951dbfb11eb
|
||
|
Signed-off-by: Sreesudhan Ramakrish Ramkumar <srramku@codeaurora.org>
|
||
|
---
|
||
|
.../platform/msm/camera_v2/isp/msm_isp_util.c | 126 +++++++++++++--------
|
||
|
.../msm/camera_v2/sensor/io/msm_camera_io_util.c | 11 ++
|
||
|
.../msm/camera_v2/sensor/io/msm_camera_io_util.h | 2 +
|
||
|
3 files changed, 89 insertions(+), 50 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 c598555..ff213fc 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
|
||
|
@@ -917,7 +917,8 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
/* Validate input parameters */
|
||
|
switch (reg_cfg_cmd->cmd_type) {
|
||
|
case VFE_WRITE:
|
||
|
- case VFE_READ: {
|
||
|
+ case VFE_READ:
|
||
|
+ case VFE_WRITE_MB: {
|
||
|
if ((reg_cfg_cmd->u.rw_info.reg_offset >
|
||
|
(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
|
||
|
((reg_cfg_cmd->u.rw_info.reg_offset +
|
||
|
@@ -943,6 +944,58 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
+
|
||
|
+ case VFE_WRITE_DMI_16BIT:
|
||
|
+ case VFE_WRITE_DMI_32BIT:
|
||
|
+ case VFE_WRITE_DMI_64BIT:
|
||
|
+ case VFE_READ_DMI_16BIT:
|
||
|
+ case VFE_READ_DMI_32BIT:
|
||
|
+ case VFE_READ_DMI_64BIT: {
|
||
|
+ 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.lo_tbl_offset) ||
|
||
|
+ (reg_cfg_cmd->u.dmi_info.hi_tbl_offset -
|
||
|
+ reg_cfg_cmd->u.dmi_info.lo_tbl_offset !=
|
||
|
+ (sizeof(uint32_t)))) {
|
||
|
+ pr_err("%s:%d hi %d lo %d\n",
|
||
|
+ __func__, __LINE__,
|
||
|
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset,
|
||
|
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ if (reg_cfg_cmd->u.dmi_info.len <= sizeof(uint32_t)) {
|
||
|
+ pr_err("%s:%d len %d\n",
|
||
|
+ __func__, __LINE__,
|
||
|
+ reg_cfg_cmd->u.dmi_info.len);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ if (((UINT_MAX -
|
||
|
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset) <
|
||
|
+ (reg_cfg_cmd->u.dmi_info.len -
|
||
|
+ sizeof(uint32_t))) ||
|
||
|
+ ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||
|
+ reg_cfg_cmd->u.dmi_info.len -
|
||
|
+ sizeof(uint32_t)) > cmd_len)) {
|
||
|
+ pr_err("%s:%d hi_tbl_offset %d len %d cmd %d\n",
|
||
|
+ __func__, __LINE__,
|
||
|
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset,
|
||
|
+ reg_cfg_cmd->u.dmi_info.len, cmd_len);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ if ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset >
|
||
|
+ (UINT_MAX - reg_cfg_cmd->u.dmi_info.len)) ||
|
||
|
+ ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
|
||
|
+ reg_cfg_cmd->u.dmi_info.len) > cmd_len)) {
|
||
|
+ pr_err("%s:%d lo_tbl_offset %d len %d cmd_len %d\n",
|
||
|
+ __func__, __LINE__,
|
||
|
+ reg_cfg_cmd->u.dmi_info.lo_tbl_offset,
|
||
|
+ reg_cfg_cmd->u.dmi_info.len, cmd_len);
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ }
|
||
|
+
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
@@ -956,39 +1009,27 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
break;
|
||
|
}
|
||
|
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);
|
||
|
+ msm_camera_io_memcpy_mb(vfe_dev->vfe_base +
|
||
|
+ reg_cfg_cmd->u.rw_info.reg_offset,
|
||
|
+ cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,
|
||
|
+ reg_cfg_cmd->u.rw_info.len);
|
||
|
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) ||
|
||
|
+ 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;
|
||
|
}
|
||
|
+ 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;
|
||
|
msm_camera_io_w(temp, vfe_dev->vfe_base +
|
||
|
reg_cfg_cmd->u.mask_info.reg_offset);
|
||
|
break;
|
||
|
@@ -1000,24 +1041,9 @@ 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 ((UINT_MAX - reg_cfg_cmd->u.dmi_info.hi_tbl_offset <
|
||
|
- reg_cfg_cmd->u.dmi_info.len -
|
||
|
- sizeof(uint32_t)) ||
|
||
|
- (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||
|
- reg_cfg_cmd->u.dmi_info.len -
|
||
|
- sizeof(uint32_t) > cmd_len)) {
|
||
|
- pr_err("Invalid Hi Table out of bounds\n");
|
||
|
- return -EINVAL;
|
||
|
- }
|
||
|
hi_tbl_ptr = cfg_data +
|
||
|
reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
|
||
|
}
|
||
|
-
|
||
|
- if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
|
||
|
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||
|
- pr_err("Invalid Lo Table out of bounds\n");
|
||
|
- return -EINVAL;
|
||
|
- }
|
||
|
lo_tbl_ptr = cfg_data +
|
||
|
reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
|
||
|
if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT)
|
||
|
@@ -1050,24 +1076,17 @@ 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_READ_DMI_64BIT) {
|
||
|
- if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||
|
- reg_cfg_cmd->u.dmi_info.len -
|
||
|
- sizeof(uint32_t) > cmd_len) {
|
||
|
- pr_err("Invalid Hi Table out of bounds\n");
|
||
|
- return -EINVAL;
|
||
|
- }
|
||
|
hi_tbl_ptr = cfg_data +
|
||
|
reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
|
||
|
}
|
||
|
|
||
|
- if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
|
||
|
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||
|
- pr_err("Invalid Lo Table out of bounds\n");
|
||
|
- return -EINVAL;
|
||
|
- }
|
||
|
lo_tbl_ptr = cfg_data +
|
||
|
reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
|
||
|
|
||
|
+ if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT)
|
||
|
+ reg_cfg_cmd->u.dmi_info.len =
|
||
|
+ reg_cfg_cmd->u.dmi_info.len / 2;
|
||
|
+
|
||
|
for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
|
||
|
lo_val = msm_camera_io_r(vfe_dev->vfe_base +
|
||
|
vfe_dev->hw_info->dmi_reg_offset + 0x4);
|
||
|
@@ -1121,7 +1140,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
if ((data_ptr < cfg_data) ||
|
||
|
(UINT_MAX / sizeof(*data_ptr) <
|
||
|
(data_ptr - cfg_data)) ||
|
||
|
- (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 +
|
||
|
@@ -1187,6 +1206,13 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||
|
case SET_WM_UB_SIZE:
|
||
|
break;
|
||
|
case SET_UB_POLICY: {
|
||
|
+
|
||
|
+ if (cmd_len < sizeof(vfe_dev->vfe_ub_policy)) {
|
||
|
+ pr_err("%s:%d failed: invalid cmd len %u exp %zu\n",
|
||
|
+ __func__, __LINE__, cmd_len,
|
||
|
+ sizeof(vfe_dev->vfe_ub_policy));
|
||
|
+ return -EINVAL;
|
||
|
+ }
|
||
|
vfe_dev->vfe_ub_policy = *cfg_data;
|
||
|
break;
|
||
|
}
|
||
|
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
|
||
|
index 78b9148..41c784a 100644
|
||
|
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
|
||
|
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
|
||
|
@@ -102,6 +102,17 @@ void msm_camera_io_memcpy(void __iomem *dest_addr,
|
||
|
msm_camera_io_dump(dest_addr, len);
|
||
|
}
|
||
|
|
||
|
+void msm_camera_io_memcpy_mb(void __iomem *dest_addr,
|
||
|
+ void __iomem *src_addr, u32 len)
|
||
|
+{
|
||
|
+ int i;
|
||
|
+ u32 *d = (u32 *) dest_addr;
|
||
|
+ u32 *s = (u32 *) src_addr;
|
||
|
+
|
||
|
+ for (i = 0; i < (len / 4); i++)
|
||
|
+ msm_camera_io_w_mb(*s++, d++);
|
||
|
+}
|
||
|
+
|
||
|
int msm_cam_clk_sel_src(struct device *dev, struct msm_cam_clk_info *clk_info,
|
||
|
struct msm_cam_clk_info *clk_src_info, int num_clk)
|
||
|
{
|
||
|
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
|
||
|
index fa9a283..2a0e21c 100644
|
||
|
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
|
||
|
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
|
||
|
@@ -38,6 +38,8 @@ u32 msm_camera_io_r_mb(void __iomem *addr);
|
||
|
void msm_camera_io_dump(void __iomem *addr, int size);
|
||
|
void msm_camera_io_memcpy(void __iomem *dest_addr,
|
||
|
void __iomem *src_addr, u32 len);
|
||
|
+void msm_camera_io_memcpy_mb(void __iomem *dest_addr,
|
||
|
+ void __iomem *src_addr, u32 len);
|
||
|
int msm_cam_clk_sel_src(struct device *dev, struct msm_cam_clk_info *clk_info,
|
||
|
struct msm_cam_clk_info *clk_src_info, int num_clk);
|
||
|
int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
|
||
|
--
|
||
|
cgit v1.1
|
||
|
|