Browse Source

msm: camera: common: Fix kernel code and add checks

Fix Kernel code and add security checks to avoid
possible null pointer dereference, out of bound
array access and accessing the uninitialized
variables. This change resolves following static
analysis issues:
568, 576, 577, 578, 4828, 4829, 4830, 4831, 4832,
4833, 4834, 4835, 4836, 4839, 4841, 4842, 5849,
9352, 9454, 9455.

CRs-fixed: 3038735
Change-Id: I16e437edbb444223ce9d275ed55089bd25a1294c
Signed-off-by: Jigar Agrawal <[email protected]>
Jigar Agrawal 3 years ago
parent
commit
35a9822e03

+ 13 - 0
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -7317,6 +7317,12 @@ static int cam_isp_blob_sfe_exp_order_update(
 
 		/* Configure cache config for WM */
 		res_id_out = order_cfg->res_type & 0xFF;
+		if (res_id_out >= CAM_SFE_HW_OUT_RES_MAX) {
+			CAM_ERR_RATE_LIMIT(CAM_ISP, "res_id_out: %d exceeds max size: %d",
+				res_id_out, CAM_SFE_HW_OUT_RES_MAX);
+			return -EINVAL;
+		}
+
 		hw_mgr_res = &ctx->res_list_sfe_out[res_id_out];
 		for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
 			if (!hw_mgr_res->hw_res[j])
@@ -8108,6 +8114,13 @@ static int cam_ife_hw_mgr_update_scratch_offset(
 		return 0;
 
 	res_id = wm_config->port_type & 0xFF;
+
+	if (res_id >= CAM_SFE_FE_RDI_NUM_MAX) {
+		CAM_ERR_RATE_LIMIT(CAM_ISP, "res_id: %d exceeds max size: %d",
+			res_id, CAM_SFE_FE_RDI_NUM_MAX);
+		return -EINVAL;
+	}
+
 	if (!ctx->sfe_info.scratch_config->buf_info[res_id].config_done) {
 		CAM_ERR(CAM_ISP,
 			"Scratch buffer not configured on ctx: %u for res: %u",

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/ife_csid_hw/cam_ife_csid_hw_ver1.c

@@ -2985,8 +2985,8 @@ int cam_ife_csid_ver1_start(void *hw_priv, void *args,
 
 		res = start_args->node_res[i];
 		if (!res || res->res_type != CAM_ISP_RESOURCE_PIX_PATH) {
-			CAM_ERR(CAM_ISP, "CSID:%d Invalid res type%d",
-				csid_hw->hw_intf->hw_idx, res->res_type);
+			CAM_ERR(CAM_ISP, "CSID:%d: res: %p, res type: %d",
+				csid_hw->hw_intf->hw_idx, res, (res) ? res->res_type : -1);
 			rc = -EINVAL;
 			goto end;
 		}

+ 14 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_bus/cam_sfe_bus_wr.c

@@ -1824,8 +1824,20 @@ static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 		evt_info.hw_idx   = sfe_out->hw_intf->hw_idx;
 		evt_info.hw_type  = CAM_ISP_HW_TYPE_SFE;
 
-		rc = cam_sfe_bus_get_comp_sfe_out_res_id_list(
+		cam_sfe_bus_get_comp_sfe_out_res_id_list(
 			comp_mask, out_list, &num_out);
+		if (num_out > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
+			CAM_ERR(CAM_ISP,
+				"num_out: %d  exceeds max_port_per_comp_grp: %d for comp_mask: %u",
+				num_out, CAM_NUM_OUT_PER_COMP_IRQ_MAX, comp_mask);
+			for (i = 0; i < num_out; i++)
+				CAM_ERR(CAM_ISP,
+					"Skipping buf done notify for outport: %u",
+					out_list[i]);
+			rc = -EINVAL;
+			goto end;
+		}
+
 		evt_info.num_res = num_out;
 		for (i = 0; i < num_out; i++) {
 			evt_info.res_id[i] = out_list[i];
@@ -1842,6 +1854,7 @@ static int cam_sfe_bus_handle_sfe_out_done_bottom_half(
 		break;
 	}
 
+end:
 	cam_sfe_bus_wr_put_evt_payload(rsrc_data->common_data, &evt_payload);
 
 	return rc;

+ 2 - 2
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_rd_ver1.c

@@ -875,13 +875,13 @@ static int cam_vfe_bus_rd_update_rm(void *priv, void *cmd_args,
 	vfe_bus_rd_data = (struct cam_vfe_bus_rd_ver1_vfe_bus_rd_data *)
 		update_buf->res->res_priv;
 
-	cdm_util_ops = vfe_bus_rd_data->cdm_util_ops;
-
 	if (!vfe_bus_rd_data || !vfe_bus_rd_data->cdm_util_ops) {
 		CAM_ERR(CAM_ISP, "Failed! Invalid data");
 		return -EINVAL;
 	}
 
+	cdm_util_ops = vfe_bus_rd_data->cdm_util_ops;
+
 	CAM_DBG(CAM_ISP, "#of RM: %d",  vfe_bus_rd_data->num_rm);
 	if (update_buf->rm_update->num_buf != vfe_bus_rd_data->num_rm) {
 		CAM_ERR(CAM_ISP,

+ 21 - 8
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver2.c

@@ -926,7 +926,6 @@ static void cam_vfe_bus_get_comp_vfe_out_res_id_list(
 		out_list[count++] = CAM_ISP_IFE_OUT_RES_DS16_DISP;
 
 	*num_out = count;
-
 }
 
 static enum cam_vfe_bus_packer_format
@@ -2501,6 +2500,8 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 
 	ctx = rsrc_data->priv;
 
+	CAM_DBG(CAM_ISP, "vfe_out %d rc %d", rsrc_data->out_type, rc);
+
 	switch (rc) {
 	case CAM_VFE_IRQ_STATUS_SUCCESS:
 		evt_id = evt_payload->evt_id;
@@ -2510,6 +2511,18 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 		if (rsrc_data->comp_grp) {
 			cam_vfe_bus_get_comp_vfe_out_res_id_list(
 				comp_mask, out_list, &num_out);
+			if (num_out > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
+				CAM_ERR(CAM_ISP,
+					"num_out: %d  exceeds max_port_per_comp_grp: %d for comp_mask: %u",
+					num_out, CAM_NUM_OUT_PER_COMP_IRQ_MAX, comp_mask);
+				for (i = 0; i < num_out; i++)
+					CAM_ERR(CAM_ISP,
+						"Skipping buf done notify for outport: %u",
+						out_list[i]);
+				rc = -EINVAL;
+				goto end;
+			}
+
 			evt_info.num_res = num_out;
 			for (i = 0; i < num_out; i++) {
 				evt_info.res_id[i] = out_list[i];
@@ -2526,8 +2539,8 @@ static int cam_vfe_bus_handle_vfe_out_done_bottom_half(
 		break;
 	}
 
+end:
 	cam_vfe_bus_put_evt_payload(rsrc_data->common_data, &evt_payload);
-	CAM_DBG(CAM_ISP, "vfe_out %d rc %d", rsrc_data->out_type, rc);
 
 	return rc;
 }
@@ -2985,13 +2998,13 @@ static int cam_vfe_bus_update_wm(void *priv, void *cmd_args,
 	vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
 		update_buf->res->res_priv;
 
-	cdm_util_ops = vfe_out_data->cdm_util_ops;
-
-	if (!vfe_out_data || !cdm_util_ops) {
+	if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
 		CAM_ERR(CAM_ISP, "Failed! Invalid data");
 		return -EINVAL;
 	}
 
+	cdm_util_ops = vfe_out_data->cdm_util_ops;
+
 	if (update_buf->wm_update->num_buf != vfe_out_data->num_wm) {
 		CAM_ERR(CAM_ISP,
 			"Failed! Invalid number buffers:%d required:%d",
@@ -3164,13 +3177,13 @@ static int cam_vfe_bus_update_hfr(void *priv, void *cmd_args,
 	vfe_out_data = (struct cam_vfe_bus_ver2_vfe_out_data *)
 		update_hfr->res->res_priv;
 
-	cdm_util_ops = vfe_out_data->cdm_util_ops;
-
-	if (!vfe_out_data || !cdm_util_ops) {
+	if (!vfe_out_data || !vfe_out_data->cdm_util_ops) {
 		CAM_ERR(CAM_ISP, "Failed! Invalid data");
 		return -EINVAL;
 	}
 
+	cdm_util_ops = vfe_out_data->cdm_util_ops;
+
 	reg_val_pair = &vfe_out_data->common_data->io_buf_update[0];
 	hfr_cfg = (struct cam_isp_port_hfr_config *)update_hfr->data;
 

+ 14 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_bus/cam_vfe_bus_ver3.c

@@ -2404,8 +2404,20 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 		evt_info.hw_idx   = vfe_out->hw_intf->hw_idx;
 		evt_info.hw_type  = CAM_ISP_HW_TYPE_VFE;
 
-		rc = cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list(
+		cam_vfe_bus_ver3_get_comp_vfe_out_res_id_list(
 			comp_mask, out_list, &num_out);
+		if (num_out > CAM_NUM_OUT_PER_COMP_IRQ_MAX) {
+			CAM_ERR(CAM_ISP,
+				"num_out: %d  exceeds max_port_per_comp_grp: %d for comp_mask: %u",
+				num_out, CAM_NUM_OUT_PER_COMP_IRQ_MAX, comp_mask);
+			for (i = 0; i < num_out; i++)
+				CAM_ERR(CAM_ISP,
+					"Skipping buf done notify for outport: %u",
+					out_list[i]);
+			rc = -EINVAL;
+			goto end;
+		}
+
 		evt_info.num_res = num_out;
 		for (i = 0; i < num_out; i++) {
 			evt_info.res_id[i] = out_list[i];
@@ -2422,6 +2434,7 @@ static int cam_vfe_bus_ver3_handle_vfe_out_done_bottom_half(
 		break;
 	}
 
+end:
 	cam_vfe_bus_ver3_put_evt_payload(rsrc_data->common_data, &evt_payload);
 
 	return rc;

+ 1 - 1
drivers/cam_sensor_module/cam_cci/cam_cci_core.c

@@ -1906,7 +1906,7 @@ int32_t cam_cci_core_cfg(struct v4l2_subdev *sd,
 	enum cci_i2c_master_t master = MASTER_MAX;
 
 	if (!cci_dev) {
-		CAM_ERR(CAM_CCI, "CCI%d_I2C_M%d CCI_DEV IS NULL", cci_dev->soc_info.index, master);
+		CAM_ERR(CAM_CCI, "CCI_DEV is null");
 		return -EINVAL;
 	}
 

+ 4 - 3
drivers/cam_sensor_module/cam_cci/cam_cci_soc.c

@@ -104,7 +104,7 @@ int cam_cci_init(struct v4l2_subdev *sd,
 	uint8_t i = 0;
 	int32_t rc = 0;
 	struct cci_device *cci_dev;
-	enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
+	enum cci_i2c_master_t master = MASTER_MAX;
 	struct cam_ahb_vote ahb_vote;
 	struct cam_axi_vote axi_vote = {0};
 	struct cam_hw_soc_info *soc_info = NULL;
@@ -113,12 +113,13 @@ int cam_cci_init(struct v4l2_subdev *sd,
 	cci_dev = v4l2_get_subdevdata(sd);
 	if (!cci_dev || !c_ctrl) {
 		CAM_ERR(CAM_CCI,
-			"CCI%d_I2C_M%d failed: invalid params cci_dev:%pK, c_ctrl:%pK",
-			cci_dev->soc_info.index, master, cci_dev, c_ctrl);
+			"Invalid params cci_dev: %p, c_ctrl: %p",
+			cci_dev, c_ctrl);
 		rc = -EINVAL;
 		return rc;
 	}
 
+	master = c_ctrl->cci_info->cci_i2c_master;
 	soc_info = &cci_dev->soc_info;
 	base = soc_info->reg_map[0].mem_base;
 

+ 5 - 0
drivers/cam_sensor_module/cam_csiphy/cam_csiphy_core.c

@@ -1305,6 +1305,11 @@ static int cam_csiphy_update_lane(
 		}
 	}
 
+	if (i == size) {
+		CAM_ERR_RATE_LIMIT(CAM_CSIPHY, "Couldnt find CSIPHY_LANE_ENABLE");
+		return -EINVAL;
+	}
+
 	lane_assign = csiphy->csiphy_info[index].lane_assign;
 
 	if (enable)

+ 3 - 2
drivers/cam_sensor_module/cam_tpg/cam_tpg_dev.c

@@ -168,11 +168,12 @@ static int tpg_soc_info_init(struct cam_tpg_device *tpg_dev,
 	struct platform_device *pdev = to_platform_device(dev);
 	struct device_node *of_node = NULL;
 
+	if (!dev || !tpg_dev)
+		return -EINVAL;
+
 	tpg_dev->soc_info.pdev = pdev;
 	tpg_dev->soc_info.dev = &pdev->dev;
 	tpg_dev->soc_info.dev_name = pdev->name;
-	if (!dev || !tpg_dev)
-		return -EINVAL;
 
 	of_node = dev->of_node;