DivestOS/Patches/Linux_CVEs/CVE-2014-9783/ANY/0001.patch

219 lines
7.1 KiB
Diff
Raw Normal View History

From 2b1050b49a9a5f7bb57006648d145e001a3eaa8b Mon Sep 17 00:00:00 2001
From: Hariram Purushothaman <hpurus@codeaurora.org>
Date: Wed, 31 Jul 2013 14:30:36 -0700
Subject: msm: camera: Fix various small issues in cci driver
Remove some unused ioctl exposed, Also add
some bound checks for ioctl user params.
Change-Id: Ifdd441fdb25fd20b005c4e4e1ebe4e203f1216ac
CRs-Fixed: 511382
Signed-off-by: Hariram Purushothaman <hpurus@codeaurora.org>
---
.../platform/msm/camera_v2/sensor/cci/msm_cci.c | 101 +++++++++++++--------
include/media/msm_cam_sensor.h | 2 +
2 files changed, 63 insertions(+), 40 deletions(-)
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
index 7f4f231..6beb92e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
@@ -41,6 +41,9 @@
/* Max bytes that can be read per CCI read transaction */
#define CCI_READ_MAX 12
+#define CCI_I2C_READ_MAX_RETRIES 3
+#define CCI_I2C_MAX_READ 8192
+#define CCI_I2C_MAX_WRITE 8192
static struct v4l2_subdev *g_cci_subdev;
@@ -87,36 +90,6 @@ static void msm_cci_set_clk_param(struct cci_device *cci_dev)
return;
}
-static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
- struct msm_camera_cci_ctrl *c_ctrl)
-{
- struct cci_device *cci_dev;
- cci_dev = v4l2_get_subdevdata(sd);
- msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
- CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
- return 0;
-}
-
-static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
- struct msm_camera_cci_ctrl *c_ctrl)
-{
- struct cci_device *cci_dev;
- uint32_t val;
- cci_dev = v4l2_get_subdevdata(sd);
- val = c_ctrl->cci_info->freq;
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
- c_ctrl->cci_info->cci_i2c_master*0x100);
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
- c_ctrl->cci_info->cci_i2c_master*0x100);
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
- c_ctrl->cci_info->cci_i2c_master*0x100);
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
- c_ctrl->cci_info->cci_i2c_master*0x100);
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
- c_ctrl->cci_info->cci_i2c_master*0x100);
- return 0;
-}
-
static void msm_cci_flush_queue(struct cci_device *cci_dev,
enum cci_i2c_master_t master)
{
@@ -213,8 +186,29 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
uint16_t cmd_size = i2c_msg->size;
struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
+
+ if (i2c_cmd == NULL) {
+ pr_err("%s:%d Failed line\n", __func__,
+ __LINE__);
+ return -EINVAL;
+ }
+
+ if ((!cmd_size) || (cmd_size > CCI_I2C_MAX_WRITE)) {
+ pr_err("%s:%d Failed line\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
CDBG("%s addr type %d data type %d\n", __func__,
i2c_msg->addr_type, i2c_msg->data_type);
+
+ if (i2c_msg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
+ pr_err("%s failed line %d\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+ if (i2c_msg->data_type >= MSM_CAMERA_I2C_DATA_TYPE_MAX) {
+ pr_err("%s failed line %d\n", __func__, __LINE__);
+ return -EINVAL;
+ }
/* assume total size within the max queue */
while (cmd_size) {
CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
@@ -321,6 +315,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
goto ERROR;
}
+ if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
+ pr_err("%s:%d More than max retries\n", __func__,
+ __LINE__);
+ goto ERROR;
+ }
+
+ if (read_cfg->data == NULL) {
+ pr_err("%s:%d Data ptr is NULL\n", __func__,
+ __LINE__);
+ goto ERROR;
+ }
+
CDBG("%s master %d, queue %d\n", __func__, master, queue);
CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
@@ -341,6 +347,11 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
goto ERROR;
}
+ if (read_cfg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
+ CDBG("%s failed line %d\n", __func__, __LINE__);
+ goto ERROR;
+ }
+
if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4) |
((read_cfg->addr & 0xFF) << 8);
@@ -454,9 +465,14 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
return -EINVAL;
}
+ if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) {
+ pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
master = c_ctrl->cci_info->cci_i2c_master;
read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
- if (!read_cfg->num_byte) {
+ if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) {
pr_err("%s:%d read num bytes 0\n", __func__, __LINE__);
rc = -EINVAL;
goto ERROR;
@@ -494,6 +510,10 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
enum cci_i2c_master_t master;
enum cci_i2c_queue_t queue = QUEUE_0;
cci_dev = v4l2_get_subdevdata(sd);
+ if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) {
+ pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
+ return -EINVAL;
+ }
master = c_ctrl->cci_info->cci_i2c_master;
CDBG("%s master %d, queue %d\n", __func__, master, queue);
CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
@@ -514,6 +534,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
__LINE__, rc);
goto ERROR;
}
+ if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
+ pr_err("%s:%d More than max retries\n", __func__,
+ __LINE__);
+ goto ERROR;
+ }
val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
c_ctrl->cci_info->retries << 16 |
@@ -533,7 +558,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
goto ERROR;
}
- msm_cci_data_queue(cci_dev, c_ctrl, queue);
+ rc = msm_cci_data_queue(cci_dev, c_ctrl, queue);
+ if (rc < 0) {
+ CDBG("%s failed line %d\n", __func__, __LINE__);
+ goto ERROR;
+ }
val = CCI_I2C_UNLOCK_CMD;
CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
@@ -703,14 +732,6 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd,
case MSM_CCI_RELEASE:
rc = msm_cci_release(sd);
break;
- case MSM_CCI_SET_SID:
- break;
- case MSM_CCI_SET_FREQ:
- rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
- break;
- case MSM_CCI_SET_SYNC_CID:
- rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
- break;
case MSM_CCI_I2C_READ:
rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
break;
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
index 2805401..da16bb8 100644
--- a/include/media/msm_cam_sensor.h
+++ b/include/media/msm_cam_sensor.h
@@ -52,6 +52,7 @@ enum msm_camera_i2c_reg_addr_type {
MSM_CAMERA_I2C_BYTE_ADDR = 1,
MSM_CAMERA_I2C_WORD_ADDR,
MSM_CAMERA_I2C_3B_ADDR,
+ MSM_CAMERA_I2C_ADDR_TYPE_MAX,
};
enum msm_camera_i2c_data_type {
@@ -62,6 +63,7 @@ enum msm_camera_i2c_data_type {
MSM_CAMERA_I2C_SET_WORD_MASK,
MSM_CAMERA_I2C_UNSET_WORD_MASK,
MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
+ MSM_CAMERA_I2C_DATA_TYPE_MAX,
};
enum msm_sensor_power_seq_type_t {
--
cgit v1.1