Ver Fonte

msm: camera: tfe: Fix errors found in KW static code analysis tool

This change fixes errors in TFE identified while running the KW static
static code analysis tool.
- The in_port member in struct cam_tfe_top_hw_info if filled incorrectly
  may lead to out of bounds access in cam_tfe_top_init.
- The reg_val_pair variable may be used uninitialized in function
  cam_tfe_top_get_reg_update.

CRs-Fixed: 3522596
Change-Id: I48c9caccaeebea3a8c6c2a12b48e5a21ba8030d5
Signed-off-by: Abhilash Kumar <[email protected]>
Abhilash Kumar há 2 anos atrás
pai
commit
1770bf062d
1 ficheiros alterados com 33 adições e 22 exclusões
  1. 33 22
      drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

+ 33 - 22
drivers/cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.c

@@ -1,7 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0-only
 /*
  * Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2024, Qualcomm Innovation Center, Inc. All rights reserved.
  */
 
 #include <linux/delay.h>
@@ -1498,32 +1498,36 @@ static int cam_tfe_top_get_reg_update(
 	struct cam_tfe_top_priv *top_priv,
 	void *cmd_args, uint32_t arg_size)
 {
-	uint32_t                             size = 0;
-	uint32_t                             reg_val_pair[2];
-	struct cam_isp_hw_get_cmd_update     *cdm_args = cmd_args;
-	struct cam_cdm_utils_ops             *cdm_util_ops = NULL;
-	struct cam_tfe_camif_data            *camif_rsrc_data = NULL;
-	struct cam_tfe_rdi_data              *rdi_rsrc_data = NULL;
-	struct cam_isp_resource_node         *in_res;
-	struct cam_isp_mode_switch_data      *mup_config = NULL;
+	int                               rc = 0;
+	uint32_t                          size = 0;
+	uint32_t                          reg_val_pair[2] = {0};
+	struct cam_isp_hw_get_cmd_update *cdm_args = cmd_args;
+	struct cam_cdm_utils_ops         *cdm_util_ops = NULL;
+	struct cam_tfe_camif_data        *camif_rsrc_data = NULL;
+	struct cam_tfe_rdi_data          *rdi_rsrc_data = NULL;
+	struct cam_isp_resource_node     *in_res;
+	struct cam_isp_mode_switch_data  *mup_config = NULL;
+	struct cam_hw_soc_info           *soc_info;
 	struct cam_tfe_top_reg_offset_common *common_reg;
-	struct cam_hw_soc_info               *soc_info;
 
 	if (arg_size != sizeof(struct cam_isp_hw_get_cmd_update)) {
 		CAM_ERR(CAM_ISP, "Invalid cmd size");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto end;
 	}
 
 	if (!cdm_args || !cdm_args->res || !top_priv) {
 		CAM_ERR(CAM_ISP, "Invalid args");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto end;
 	}
 
 	cdm_util_ops = (struct cam_cdm_utils_ops *)cdm_args->res->cdm_ops;
 
 	if (!cdm_util_ops) {
 		CAM_ERR(CAM_ISP, "Invalid CDM ops");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto end;
 	}
 
 	soc_info = top_priv->common_data.soc_info;
@@ -1533,7 +1537,8 @@ static int cam_tfe_top_get_reg_update(
 	if ((!cdm_args->reg_write) && ((size * 4) > cdm_args->cmd.size)) {
 		CAM_ERR(CAM_ISP, "buf size:%d is not sufficient, expected: %d",
 			cdm_args->cmd.size, size);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto end;
 	}
 
 	if (in_res->res_id == CAM_ISP_HW_TFE_IN_CAMIF) {
@@ -1551,7 +1556,11 @@ static int cam_tfe_top_get_reg_update(
 		CAM_DBG(CAM_ISP, "Reg update not supported for res %d",
 			in_res->res_id);
 		cdm_args->cmd.used_bytes = 0;
-		return 0;
+		goto end;
+	} else {
+		CAM_ERR(CAM_ISP, "Unknown resource with res_id = %d", in_res->res_id);
+		rc = -EINVAL;
+		goto end;
 	}
 
 	common_reg = top_priv->common_data.common_reg;
@@ -1573,11 +1582,11 @@ static int cam_tfe_top_get_reg_update(
 	} else {
 		cdm_util_ops->cdm_write_regrandom(cdm_args->cmd.cmd_buf_addr,
 			1, reg_val_pair);
-
 		cdm_args->cmd.used_bytes = size * 4;
 	}
 
-	return 0;
+end:
+	return rc;
 }
 
 static int cam_tfe_top_init_config_update(
@@ -2893,8 +2902,8 @@ int cam_tfe_top_init(
 				hw_info->ppp_hw_info.ppp_reg;
 			ppp_priv->reg_data    =
 				hw_info->ppp_hw_info.reg_data;
-		} else if (hw_info->in_port[i] ==
-			CAM_TFE_RDI_VER_1_0) {
+		} else if (hw_info->in_port[i] == CAM_TFE_RDI_VER_1_0 &&
+				(j < CAM_TFE_RDI_MAX)) {
 			top_priv->in_rsrc[i].res_id =
 				CAM_ISP_HW_TFE_IN_RDI0 + j;
 
@@ -2918,8 +2927,8 @@ int cam_tfe_top_init(
 			rdi_priv->reg_data =
 				hw_info->rdi_hw_info[j++].reg_data;
 		}  else {
-			CAM_WARN(CAM_ISP, "TFE:%d Invalid inport type: %u",
-				core_info->core_index, hw_info->in_port[i]);
+			CAM_WARN(CAM_ISP, "TFE:%d Invalid inport type: %u at i = %d. j = %d",
+				core_info->core_index, hw_info->in_port[i], i, j);
 		}
 	}
 
@@ -3375,7 +3384,8 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 
 	if (!hw_priv) {
 		CAM_ERR(CAM_ISP, "Invalid arguments");
-		return -EINVAL;
+		rc = -EINVAL;
+		goto end;
 	}
 
 	soc_info = &tfe_hw->soc_info;
@@ -3463,6 +3473,7 @@ int cam_tfe_process_cmd(void *hw_priv, uint32_t cmd_type,
 		break;
 	}
 
+end:
 	if (rc) {
 		CAM_ERR(CAM_ISP, "TFE: %d error with cmd type: %d",
 			core_info->core_index, cmd_type);