DivestOS/Patches/Linux_CVEs/CVE-2017-11018/ANY/0001.patch

532 lines
15 KiB
Diff
Raw Normal View History

2017-11-07 17:32:46 -05:00
From 1d718286c4c482502a2c4356cebef28aef2fb01f Mon Sep 17 00:00:00 2001
From: Rahul Sharma <sharah@codeaurora.org>
Date: Wed, 28 Jun 2017 15:46:19 +0530
Subject: msm: vfe : Fix for multiple buffer over read/write
Implemented validation of user space values in ioctl call
before processing buffers in response to user commands.
Change-Id: Icf6e49650bab358b764ebf1db24925a4063c5842
Signed-off-by: Rahul Sharma <sharah@codeaurora.org>
---
drivers/media/video/msm/vfe/msm_vfe32.c | 246 ++++++++++++++++++++++++++++++++
1 file changed, 246 insertions(+)
diff --git a/drivers/media/video/msm/vfe/msm_vfe32.c b/drivers/media/video/msm/vfe/msm_vfe32.c
index 64f3e7b..1509a04 100644
--- a/drivers/media/video/msm/vfe/msm_vfe32.c
+++ b/drivers/media/video/msm/vfe/msm_vfe32.c
@@ -2275,6 +2275,7 @@ static int vfe32_proc_general(
uint32_t *cmdp_local = NULL;
uint32_t snapshot_cnt = 0;
uint32_t temp1 = 0, temp2 = 0;
+ uint32_t maxvalue = 0;
struct msm_camera_vfe_params_t vfe_params;
switch (cmd->id) {
@@ -2373,6 +2374,14 @@ static int vfe32_proc_general(
__func__);
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2407,6 +2416,14 @@ static int vfe32_proc_general(
__func__);
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2441,6 +2458,14 @@ static int vfe32_proc_general(
__func__);
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2471,6 +2496,14 @@ static int vfe32_proc_general(
__func__);
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2502,6 +2535,14 @@ static int vfe32_proc_general(
__func__);
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2527,6 +2568,14 @@ static int vfe32_proc_general(
__func__);
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2589,6 +2638,14 @@ static int vfe32_proc_general(
VFE_STATS_CFG);
msm_camera_io_w(module_val,
vfe32_ctrl->share_ctrl->vfebase + VFE_MODULE_CFG);
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2627,6 +2684,10 @@ static int vfe32_proc_general(
new_val = *cmdp_local;
old_val &= MCE_EN_MASK;
new_val = new_val | old_val;
+ if (cmd->length < 4) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_CHROMA_SUP_OFF + 4, &new_val, 4);
@@ -2637,10 +2698,23 @@ static int vfe32_proc_general(
new_val = *cmdp_local;
old_val &= MCE_Q_K_MASK;
new_val = new_val | old_val;
+ if (cmd->length < (4 + sizeof(uint32_t)*1)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_CHROMA_SUP_OFF + 8, &new_val, 4);
cmdp_local += 1;
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < (vfe32_cmd[cmd->id].length +
+ sizeof(uint32_t) * (1 + 1))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
vfe32_cmd[cmd->id].offset,
@@ -2661,6 +2735,10 @@ static int vfe32_proc_general(
goto proc_general_done;
}
cmdp_local = cmdp;
+ if (cmd->length < 4) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
V32_CHROMA_SUP_OFF, cmdp_local, 4);
@@ -2673,6 +2751,11 @@ static int vfe32_proc_general(
V32_CHROMA_SUP_OFF + 4);
old_val &= ~MCE_EN_MASK;
new_val = new_val | old_val;
+ /* As cmdp_local got incremented by 1*/
+ if (cmd->length < (4 + sizeof(uint32_t) * 1)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_CHROMA_SUP_OFF + 4, &new_val, 4);
@@ -2683,6 +2766,10 @@ static int vfe32_proc_general(
new_val = *cmdp_local;
old_val &= ~MCE_Q_K_MASK;
new_val = new_val | old_val;
+ if (cmd->length < (4 + sizeof(uint32_t) * (1 + 1))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_CHROMA_SUP_OFF + 8, &new_val, 4);
@@ -2704,12 +2791,22 @@ static int vfe32_proc_general(
goto proc_general_done;
}
cmdp_local = cmdp;
+ if (cmd->length < 16) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
vfe32_cmd[cmd->id].offset,
cmdp_local, 16);
cmdp_local += 4;
vfe32_program_dmi_cfg(ROLLOFF_RAM0_BANK0, vfe32_ctrl);
+ if (cmd->length < (sizeof(uint32_t) *
+ (4 + V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2 +
+ V32_MESH_ROLL_OFF_DELTA_TABLE_SIZE * 2))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
/* for loop for extrcting init table. */
for (i = 0; i < (V32_MESH_ROLL_OFF_INIT_TABLE_SIZE * 2); i++) {
msm_camera_io_w(*cmdp_local ,
@@ -2773,6 +2870,14 @@ static int vfe32_proc_general(
}
break;
case VFE_CMD_LA_CFG:
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2813,6 +2918,11 @@ static int vfe32_proc_general(
cmdp_local = cmdp + 1;
old_val = msm_camera_io_r(
vfe32_ctrl->share_ctrl->vfebase + V32_LA_OFF);
+ if (cmd->length < (sizeof(uint32_t) * (1 +
+ (VFE32_LA_TABLE_LENGTH / 2)))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
if (old_val != 0x0)
vfe32_write_la_cfg(LUMA_ADAPT_LUT_RAM_BANK0,
cmdp_local, vfe32_ctrl);
@@ -2861,6 +2971,10 @@ static int vfe32_proc_general(
break;
case VFE_CMD_SK_ENHAN_CFG:
case VFE_CMD_SK_ENHAN_UPDATE:{
+ if (cmd->length < V32_SCE_LEN) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -2895,17 +3009,31 @@ static int vfe32_proc_general(
goto proc_general_done;
}
cmdp_local = cmdp;
+ if (cmd->length < V32_LINEARIZATION_LEN1) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_LINEARIZATION_OFF1,
cmdp_local, V32_LINEARIZATION_LEN1);
cmdp_local += 4;
+ if (cmd->length < (V32_LINEARIZATION_LEN2 +
+ sizeof(uint32_t) * 4)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_LINEARIZATION_OFF2,
cmdp_local, V32_LINEARIZATION_LEN2);
cmdp_local = cmdp + 17;
+ if (cmd->length < (sizeof(uint32_t) *
+ (VFE32_LINEARIZATON_TABLE_LENGTH + 17))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
cmdp_local, vfe32_ctrl);
break;
@@ -2923,11 +3051,20 @@ static int vfe32_proc_general(
}
cmdp_local = cmdp;
cmdp_local++;
+ if (cmd->length < V32_LINEARIZATION_LEN1) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_LINEARIZATION_OFF1 + 4,
cmdp_local, (V32_LINEARIZATION_LEN1 - 4));
cmdp_local += 3;
+ if (cmd->length < (V32_LINEARIZATION_LEN2 +
+ sizeof(uint32_t) * (1 + 3))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_LINEARIZATION_OFF2,
@@ -2938,6 +3075,11 @@ static int vfe32_proc_general(
vfe32_ctrl->share_ctrl->vfebase +
V32_LINEARIZATION_OFF1);
+ if (cmd->length < (sizeof(uint32_t) *
+ (VFE32_LINEARIZATON_TABLE_LENGTH + 17))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
if (old_val != 0x0)
vfe32_write_linear_cfg(BLACK_LUT_RAM_BANK0,
cmdp_local, vfe32_ctrl);
@@ -3084,11 +3226,24 @@ static int vfe32_proc_general(
new_val = new_val | old_val;
*cmdp_local = new_val;
+ if (cmd->length < 4) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
cmdp_local, 4);
cmdp_local += 1;
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < (vfe32_cmd[cmd->id].length +
+ sizeof(uint32_t) * 1)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
vfe32_cmd[cmd->id].offset,
@@ -3118,10 +3273,23 @@ static int vfe32_proc_general(
new_val = new_val | old_val;
*cmdp_local = new_val;
+ if (cmd->length < 4) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase + V32_DEMOSAICV3_0_OFF,
cmdp_local, 4);
cmdp_local += 1;
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < (vfe32_cmd[cmd->id].length +
+ sizeof(uint32_t) * 1)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
vfe32_cmd[cmd->id].offset,
@@ -3150,9 +3318,18 @@ static int vfe32_proc_general(
new_val = new_val | old_val;
*cmdp_local = new_val;
+ if (cmd->length < V32_DEMOSAICV3_LEN) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
V32_DEMOSAICV3_0_OFF,
cmdp_local, V32_DEMOSAICV3_LEN);
+ if (cmd->length < (V32_DEMOSAICV3_DBPC_LEN +
+ sizeof(uint32_t) * 4)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp_local += 1;
msm_camera_io_memcpy(vfe32_ctrl->share_ctrl->vfebase +
V32_DEMOSAICV3_DBPC_CFG_OFF,
@@ -3183,6 +3360,11 @@ static int vfe32_proc_general(
rc = -EFAULT;
goto proc_general_done;
}
+ if (cmd->length < (sizeof(uint32_t) * (1 +
+ VFE32_GAMMA_NUM_ENTRIES / 2))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF,
cmdp, 4);
@@ -3207,6 +3389,16 @@ static int vfe32_proc_general(
rc = -EFAULT;
goto proc_general_done;
}
+ maxvalue = (VFE32_GAMMA_CH0_G_POS > VFE32_GAMMA_CH1_B_POS) ?
+ VFE32_GAMMA_CH0_G_POS : VFE32_GAMMA_CH1_B_POS;
+ maxvalue = (maxvalue > VFE32_GAMMA_CH2_R_POS) ?
+ maxvalue : VFE32_GAMMA_CH2_R_POS;
+
+ if (cmd->length < (sizeof(uint32_t) * (1 +
+ maxvalue + (VFE32_GAMMA_NUM_ENTRIES / 2)))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF,
cmdp, 4);
@@ -3236,6 +3428,17 @@ static int vfe32_proc_general(
old_val = msm_camera_io_r(
vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
cmdp += 1;
+
+ maxvalue = (VFE32_GAMMA_CH0_G_POS > VFE32_GAMMA_CH1_B_POS) ?
+ VFE32_GAMMA_CH0_G_POS : VFE32_GAMMA_CH1_B_POS;
+ maxvalue = (maxvalue > VFE32_GAMMA_CH2_R_POS) ?
+ maxvalue : VFE32_GAMMA_CH2_R_POS;
+
+ if (cmd->length < (sizeof(uint32_t) * (1 +
+ maxvalue + (VFE32_GAMMA_NUM_ENTRIES / 2)))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
if (old_val != 0x0) {
vfe32_write_gamma_cfg(RGBLUT_RAM_CH0_BANK0,
cmdp + VFE32_GAMMA_CH0_G_POS, vfe32_ctrl);
@@ -3271,6 +3474,11 @@ static int vfe32_proc_general(
old_val = msm_camera_io_r(
vfe32_ctrl->share_ctrl->vfebase + V32_RGB_G_OFF);
cmdp += 1;
+ if (cmd->length < (sizeof(uint32_t) * (1 + (
+ VFE32_GAMMA_NUM_ENTRIES / 2)))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
if (old_val != 0x0) {
vfe32_write_gamma_cfg(
RGBLUT_RAM_CH0_BANK0, cmdp, vfe32_ctrl);
@@ -3442,10 +3650,24 @@ static int vfe32_proc_general(
rc = -EFAULT;
goto proc_general_done;
}
+ /* As cmdp gets incremented 7 times in function
+ vfe32_sync_timer_start() */
+ if (cmd->length < (sizeof(uint32_t) * 7)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
vfe32_sync_timer_start(cmdp, vfe32_ctrl);
break;
case VFE_CMD_MODULE_CFG: {
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -3496,11 +3718,24 @@ static int vfe32_proc_general(
rc = -EFAULT;
goto proc_general_done;
}
+ if (cmd->id < 0 || cmd->id >= ARRAY_SIZE(vfe32_cmd)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
+ if (cmd->length < vfe32_cmd[cmd->id].length) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
vfe32_cmd[cmd->id].offset,
cmdp, (vfe32_cmd[cmd->id].length));
cmdp_local = cmdp + V32_ASF_LEN/4;
+ if (cmd->length < (sizeof(uint32_t) * (V32_ASF_LEN / 4) +
+ V32_ASF_SPECIAL_EFX_CFG_LEN)) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
msm_camera_io_memcpy(
vfe32_ctrl->share_ctrl->vfebase +
V32_ASF_SPECIAL_EFX_CFG_OFF,
@@ -3508,6 +3743,12 @@ static int vfe32_proc_general(
break;
case VFE_CMD_PCA_ROLL_OFF_CFG:
+
+ if (cmd->length < (sizeof(uint32_t) * (8 + 4 *
+ V33_PCA_ROLL_OFF_TABLE_SIZE))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
@@ -3566,6 +3807,11 @@ static int vfe32_proc_general(
break;
case VFE_CMD_PCA_ROLL_OFF_UPDATE:
+ if (cmd->length < (sizeof(uint32_t) * (8 + 4 *
+ V33_PCA_ROLL_OFF_TABLE_SIZE))) {
+ rc = -EINVAL;
+ goto proc_general_done;
+ }
cmdp = kmalloc(cmd->length, GFP_ATOMIC);
if (!cmdp) {
rc = -ENOMEM;
--
cgit v1.1