DivestOS/Patches/Linux_CVEs/CVE-2016-6741/3.18/0002.patch
2017-11-07 17:32:46 -05:00

138 lines
4.6 KiB
Diff

From d291eebd8e43bba3229ae7ef9146a132894dc293 Mon Sep 17 00:00:00 2001
From: Samyukta Mogily <smogily@codeaurora.org>
Date: Thu, 8 Sep 2016 17:35:52 +0530
Subject: msm: camera: Restructure data handling to be more robust
Use dynamic array allocation instead of static array to
prevent stack overflow.
User-supplied number of bytes may result in integer overflow.
To fix this we check that the num_byte isn't above 8K size.
CRs-Fixed: 1060554
Change-Id: I407b5ec8cdc2ac7f3b491644418d3eb1101ce65a
Signed-off-by: Samyukta Mogily <smogily@codeaurora.org>
---
.../msm/camera_v2/sensor/io/msm_camera_cci_i2c.c | 6 ++++
.../msm/camera_v2/sensor/io/msm_camera_qup_i2c.c | 39 ++++++++++++++++++++--
2 files changed, 43 insertions(+), 2 deletions(-)
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
index a4ee504..27d4f5e 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_cci_i2c.c
@@ -69,6 +69,12 @@ int32_t msm_camera_cci_i2c_read_seq(struct msm_camera_i2c_client *client,
|| num_byte == 0)
return rc;
+ if (num_byte > I2C_REG_DATA_MAX) {
+ pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n",
+ __func__, num_byte, I2C_REG_DATA_MAX);
+ return rc;
+ }
+
buf = kzalloc(num_byte, GFP_KERNEL);
if (!buf) {
pr_err("%s:%d no memory\n", __func__, __LINE__);
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
index 7a0fb97..7d21866 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_qup_i2c.c
@@ -73,7 +73,7 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
enum msm_camera_i2c_data_type data_type)
{
int32_t rc = -EFAULT;
- unsigned char buf[client->addr_type+data_type];
+ unsigned char *buf = NULL;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
&& client->addr_type != MSM_CAMERA_I2C_WORD_ADDR)
@@ -81,6 +81,17 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
&& data_type != MSM_CAMERA_I2C_WORD_DATA))
return rc;
+ if (client->addr_type > UINT_MAX - data_type) {
+ pr_err("%s: integer overflow prevented\n", __func__);
+ return rc;
+ }
+
+ buf = kzalloc(client->addr_type+data_type, GFP_KERNEL);
+ if (!buf) {
+ pr_err("%s:%d no memory\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+
if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
buf[0] = addr;
} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
@@ -90,6 +101,8 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
rc = msm_camera_qup_i2c_rxdata(client, buf, data_type);
if (rc < 0) {
S_I2C_DBG("%s fail\n", __func__);
+ kfree(buf);
+ buf = NULL;
return rc;
}
@@ -99,6 +112,8 @@ int32_t msm_camera_qup_i2c_read(struct msm_camera_i2c_client *client,
*data = buf[0] << 8 | buf[1];
S_I2C_DBG("%s addr = 0x%x data: 0x%x\n", __func__, addr, *data);
+ kfree(buf);
+ buf = NULL;
return rc;
}
@@ -106,7 +121,7 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
uint32_t addr, uint8_t *data, uint32_t num_byte)
{
int32_t rc = -EFAULT;
- unsigned char buf[client->addr_type+num_byte];
+ unsigned char *buf = NULL;
int i;
if ((client->addr_type != MSM_CAMERA_I2C_BYTE_ADDR
@@ -114,6 +129,22 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
|| num_byte == 0)
return rc;
+ if (num_byte > I2C_REG_DATA_MAX) {
+ pr_err("%s: Error num_byte:0x%x exceeds 8K max supported:0x%x\n",
+ __func__, num_byte, I2C_REG_DATA_MAX);
+ return rc;
+ }
+ if (client->addr_type > UINT_MAX - num_byte) {
+ pr_err("%s: integer overflow prevented\n", __func__);
+ return rc;
+ }
+
+ buf = kzalloc(client->addr_type+num_byte, GFP_KERNEL);
+ if (!buf) {
+ pr_err("%s:%d no memory\n", __func__, __LINE__);
+ return -ENOMEM;
+ }
+
if (client->addr_type == MSM_CAMERA_I2C_BYTE_ADDR) {
buf[0] = addr;
} else if (client->addr_type == MSM_CAMERA_I2C_WORD_ADDR) {
@@ -123,6 +154,8 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
rc = msm_camera_qup_i2c_rxdata(client, buf, num_byte);
if (rc < 0) {
S_I2C_DBG("%s fail\n", __func__);
+ kfree(buf);
+ buf = NULL;
return rc;
}
@@ -132,6 +165,8 @@ int32_t msm_camera_qup_i2c_read_seq(struct msm_camera_i2c_client *client,
S_I2C_DBG("Byte %d: 0x%x\n", i, buf[i]);
S_I2C_DBG("Data: 0x%x\n", data[i]);
}
+ kfree(buf);
+ buf = NULL;
return rc;
}
--
cgit v1.1