Bladeren bron

msm: camera: tfe: fixes for OOB and null ptr issues

Add validation checks in CRE, ICP and TFE drivers
to avoid OOB and null ptr access issues.

CRs-Fixed: 3248380
Change-Id: Ic2c6bd41e34605a3291e6f50fe0fe94a0ab30523
Signed-off-by: Nirmal Abraham <[email protected]>
(cherry picked from commit a63bcb668392e1271ab0d2f53a54736a54325828)
Nirmal Abraham 3 jaren geleden
bovenliggende
commit
cbf5607d03

+ 9 - 1
drivers/cam_cre/cam_cre_hw_mgr/cam_cre_hw_mgr.c

@@ -796,6 +796,12 @@ static int cam_cre_mgr_process_cmd(void *priv, void *data)
 	hw_mgr = task_data->data;
 	num_batch = cre_req->num_batch;
 
+	if (num_batch > CRE_MAX_BATCH_SIZE) {
+		CAM_WARN(CAM_CRE, "num_batch = %u is greater than max",
+				num_batch);
+		num_batch = CRE_MAX_BATCH_SIZE;
+	}
+
 	CAM_DBG(CAM_CRE,
 		"Ctx %d Going to configure cre for req %d, req_idx %d num_batch %d",
 		ctx_data->ctx_id, cre_req->request_id, cre_req->req_idx, num_batch);
@@ -880,8 +886,10 @@ static int32_t cam_cre_mgr_process_msg(void *priv, void *data)
 		active_req_idx, ctx->last_done_req_idx);
 
 	active_req = ctx->req_list[active_req_idx];
-	if (!active_req)
+	if (!active_req) {
 		CAM_ERR(CAM_CRE, "Active req cannot be null");
+		return -EINVAL;
+	}
 
 	if (irq_data.error) {
 		evt_id = CAM_CTX_EVT_ID_ERROR;

+ 7 - 6
drivers/cam_cre/cam_cre_hw_mgr/cre_hw/bus_rd/cre_bus_rd.c

@@ -225,7 +225,7 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
 	struct cre_io_buf *io_buf;
 	struct cam_cre_bus_rd_reg *rd_reg;
 	struct cam_cre_bus_rd_reg_val *rd_reg_val;
-	struct cre_reg_buffer *cre_reg_buf;
+	struct cre_reg_buffer *cre_reg_buf = NULL;
 
 	int val;
 
@@ -269,11 +269,12 @@ static int cam_cre_bus_rd_prepare(struct cam_cre_hw *cam_cre_hw_info,
 			rd_reg->offset + rd_reg->input_if_cmd,
 			val);
 	}
-
-	for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
-		CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x",
-				cre_reg_buf->rd_reg_set[i].value,
-				cre_reg_buf->rd_reg_set[i].offset);
+	if (cre_reg_buf) {
+		for (i = 0; i < cre_reg_buf->num_rd_reg_set; i++) {
+			CAM_DBG(CAM_CRE, "CRE value 0x%x offset 0x%x",
+					cre_reg_buf->rd_reg_set[i].value,
+					cre_reg_buf->rd_reg_set[i].offset);
+		}
 	}
 end:
 	return 0;

+ 9 - 1
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_csid_hw/cam_tfe_csid_core.c

@@ -736,7 +736,6 @@ static int cam_tfe_csid_cid_reserve(struct cam_tfe_csid_hw *csid_hw,
 		rc = -EINVAL;
 		goto end;
 	}
-
 	/* CSID  CSI2 v1.1 supports 4 vc  */
 	for (i = 0; i < cid_reserv->in_port->num_valid_vc_dt; i++) {
 		if (cid_reserv->in_port->dt[i] > 0x3f ||
@@ -839,6 +838,15 @@ static int cam_tfe_csid_path_reserve(struct cam_tfe_csid_hw *csid_hw,
 	struct cam_isp_resource_node    *res;
 	uint32_t          cid_value;
 
+	if (reserve->in_port->num_valid_vc_dt == 0 ||
+		reserve->in_port->num_valid_vc_dt > CAM_ISP_TFE_VC_DT_CFG) {
+		CAM_ERR(CAM_ISP, "CSID:%d invalid num_valid_vc_dt: %d",
+			csid_hw->hw_intf->hw_idx,
+			reserve->in_port->num_valid_vc_dt);
+		rc = -EINVAL;
+		goto end;
+	}
+
 	/* CSID  CSI2 v2.0 supports 4 vc */
 	for (i = 0; i < reserve->in_port->num_valid_vc_dt; i++) {
 		if (reserve->in_port->dt[i] > 0x3f ||

+ 9 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_bus.c

@@ -2172,7 +2172,7 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
 	struct cam_buf_io_cfg                *io_cfg;
 	struct cam_tfe_bus_tfe_out_data      *tfe_out_data = NULL;
 	struct cam_tfe_bus_wm_resource_data  *wm_data = NULL;
-	struct cam_cdm_utils_ops             *cdm_util_ops;
+	struct cam_cdm_utils_ops             *cdm_util_ops = NULL;
 	uint32_t *reg_val_pair;
 	uint32_t num_regval_pairs = 0;
 	uint32_t i, j, size = 0;
@@ -2184,13 +2184,13 @@ static int cam_tfe_bus_update_wm(void *priv, void *cmd_args,
 	tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
 		update_buf->res->res_priv;
 
-	cdm_util_ops = tfe_out_data->cdm_util_ops;
-
-	if (!tfe_out_data || !cdm_util_ops) {
-		CAM_ERR(CAM_ISP, "Failed! Invalid data");
+	if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
+		CAM_ERR(CAM_ISP, "Failed! invalid data");
 		return -EINVAL;
 	}
 
+	cdm_util_ops = tfe_out_data->cdm_util_ops;
+
 	if (update_buf->wm_update->num_buf != tfe_out_data->num_wm) {
 		CAM_ERR(CAM_ISP,
 			"Failed! Invalid number buffers:%d required:%d",
@@ -2294,7 +2294,7 @@ static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
 	struct cam_isp_hw_get_cmd_update         *update_hfr;
 	struct cam_tfe_bus_tfe_out_data          *tfe_out_data = NULL;
 	struct cam_tfe_bus_wm_resource_data      *wm_data = NULL;
-	struct cam_cdm_utils_ops                 *cdm_util_ops;
+	struct cam_cdm_utils_ops                 *cdm_util_ops = NULL;
 	struct cam_isp_tfe_port_hfr_config       *hfr_cfg = NULL;
 	uint32_t *reg_val_pair;
 	uint32_t num_regval_pairs = 0;
@@ -2306,13 +2306,12 @@ static int cam_tfe_bus_update_hfr(void *priv, void *cmd_args,
 	tfe_out_data = (struct cam_tfe_bus_tfe_out_data *)
 		update_hfr->res->res_priv;
 
-	cdm_util_ops = tfe_out_data->cdm_util_ops;
-
-	if (!tfe_out_data || !cdm_util_ops) {
-		CAM_ERR(CAM_ISP, "Failed! Invalid data");
+	if (!tfe_out_data || !(tfe_out_data->cdm_util_ops)) {
+		CAM_ERR(CAM_ISP, "Failed! invalid data");
 		return -EINVAL;
 	}
 
+	cdm_util_ops = tfe_out_data->cdm_util_ops;
 	reg_val_pair = &tfe_out_data->common_data->io_buf_update[0];
 	hfr_cfg = (struct cam_isp_tfe_port_hfr_config *)update_hfr->data;