Browse Source

msm: camera: isp: fix potential out of bounds

This change fix multiple prevent issues.
fix over bound array access, add NULL checks,
fix format specifier and fix typecasting.

CRs-Fixed: 3643117
Change-Id: I16b4405c52ae9a6c53f6ff954dc32735719a99ad
Signed-off-by: Vikram Sharma <[email protected]>
Vikram Sharma 1 year ago
parent
commit
5d36106df2

+ 4 - 4
drivers/cam_isp/cam_isp_context.c

@@ -4906,7 +4906,7 @@ static inline int cam_isp_context_apply_evt_injection(struct cam_context *ctx)
 
 static inline void __cam_isp_ctx_update_fcg_prediction_idx(
 	struct cam_context                      *ctx,
-	uint32_t                                 request_id,
+	uint64_t                                 request_id,
 	struct cam_isp_fcg_prediction_tracker   *fcg_tracker,
 	struct cam_isp_fcg_config_info          *fcg_info)
 {
@@ -9261,7 +9261,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 	if (rc) {
 		CAM_ERR(CAM_ISP, "Camera Context Base init failed, ctx_idx: %u, link: 0x%x",
 			ctx_base->ctx_id, ctx_base->link_hdl);
-		goto err;
+		goto free_mem;
 	}
 
 	/* FCG related struct setup */
@@ -9273,7 +9273,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 				"Failed to allocate memory for FCG struct, ctx_idx: %u, link: %x",
 				ctx_base->ctx_id, ctx_base->link_hdl);
 			rc = -ENOMEM;
-			goto kfree;
+			goto free_mem;
 		}
 
 		list_add_tail(&skip_info->list, &ctx->fcg_tracker.skipped_list);
@@ -9300,7 +9300,7 @@ int cam_isp_context_init(struct cam_isp_context *ctx,
 
 	return rc;
 
-kfree:
+free_mem:
 	list_for_each_entry_safe(skip_info, temp,
 		&ctx->fcg_tracker.skipped_list, list) {
 		list_del(&skip_info->list);

+ 4 - 4
drivers/cam_isp/cam_isp_dev.c

@@ -226,7 +226,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
 		g_isp_dev.isp_device_type);
 	if (rc != 0) {
 		CAM_ERR(CAM_ISP, "Can not initialized ISP HW manager!");
-		goto kfree;
+		goto free_mem;
 	}
 
 	for (i = 0; i < g_isp_dev.max_context; i++) {
@@ -238,7 +238,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
 			g_isp_dev.isp_device_type, iommu_hdl);
 		if (rc) {
 			CAM_ERR(CAM_ISP, "ISP context init failed!");
-			goto kfree;
+			goto free_mem;
 		}
 	}
 
@@ -250,7 +250,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
 
 	if (rc) {
 		CAM_ERR(CAM_ISP, "ISP node init failed!");
-		goto kfree;
+		goto free_mem;
 	}
 
 	node->sd_handler = cam_isp_subdev_close_internal;
@@ -263,7 +263,7 @@ static int cam_isp_dev_component_bind(struct device *dev,
 
 	return 0;
 
-kfree:
+free_mem:
 	kfree(g_isp_dev.ctx);
 	g_isp_dev.ctx = NULL;
 	kfree(g_isp_dev.ctx_isp);

+ 4 - 4
drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

@@ -6955,7 +6955,7 @@ static int cam_isp_blob_fcg_update(
 			rc = res->hw_intf->hw_ops.process_cmd(
 				res->hw_intf->hw_priv,
 				CAM_ISP_HW_CMD_FCG_CONFIG,
-				&fcg_cmd, sizeof(struct cam_isp_hw_fcg_cmd));
+				&fcg_cmd, (uint32_t)sizeof(struct cam_isp_hw_fcg_cmd));
 			if (rc) {
 				CAM_ERR(CAM_ISP,
 					"Failed in writing FCG values to the hw update entry, rc: %d, request id: %llu",
@@ -7204,7 +7204,7 @@ static int cam_ife_mgr_config_hw(
 skip_bw_clk_update:
 	rc = cam_ife_mgr_apply_fcg_update(ctx, hw_update_data, cfg);
 	if (rc) {
-		CAM_ERR(CAM_ISP, "Failed in updating FCG values", ctx->ctx_index);
+		CAM_ERR(CAM_ISP, "Failed in updating FCG values %u", ctx->ctx_index);
 		return rc;
 	}
 
@@ -10874,7 +10874,7 @@ static int cam_isp_blob_fcg_config_prepare(
 		"Start storing FCG config in req_isp on ctx_idx: %u, hw_type: %d, request_id: %llu",
 		ctx->ctx_index, hw_type, request_id);
 
-	fcg_size = sizeof(struct cam_isp_generic_fcg_config);
+	fcg_size = (uint32_t)sizeof(struct cam_isp_generic_fcg_config);
 	fcg_size += (fcg_config_args->num_ch_ctx - 1) *
 		sizeof(struct cam_isp_ch_ctx_fcg_config);
 	fcg_size += fcg_config_args->num_ch_ctx *
@@ -12945,7 +12945,7 @@ static int cam_ife_hw_mgr_add_fcg_update(
 			rc = res->hw_intf->hw_ops.process_cmd(
 				res->hw_intf->hw_priv,
 				CAM_ISP_HW_CMD_FCG_CONFIG, &fcg_cmd,
-				sizeof(struct cam_isp_hw_fcg_cmd));
+				(uint32_t)sizeof(struct cam_isp_hw_fcg_cmd));
 			if (rc || (fcg_cmd.u.fcg_get_size.kmd_size == 0)) {
 				CAM_ERR(CAM_ISP,
 					"Failed in retrieving KMD buf size requirement, rc: %d",

+ 15 - 8
drivers/cam_isp/isp_hw_mgr/isp_hw/sfe_hw/sfe_top/cam_sfe_top.c

@@ -1163,7 +1163,7 @@ static int cam_sfe_top_apply_fcg_update(
 	uint32_t                                     num_regval_pairs = 0;
 	int                                          rc = 0, i, j = 0;
 
-	if (!top_priv || (fcg_update->prediction_idx == 0)) {
+	if (!top_priv || !fcg_update || (fcg_update->prediction_idx == 0)) {
 		CAM_ERR(CAM_SFE, "Invalid args");
 		return -EINVAL;
 	}
@@ -1181,6 +1181,12 @@ static int cam_sfe_top_apply_fcg_update(
 		return -EINVAL;
 	}
 
+	if (fcg_config->num_ch_ctx > CAM_ISP_MAX_FCG_CH_CTXS) {
+		CAM_ERR(CAM_SFE, "out of bound %d",
+				fcg_config->num_ch_ctx);
+		return -EINVAL;
+	}
+
 	reg_val_pair = kcalloc(fcg_module_info->max_reg_val_pair_size, sizeof(uint32_t),
 		GFP_KERNEL);
 	if (!reg_val_pair) {
@@ -1189,19 +1195,20 @@ static int cam_sfe_top_apply_fcg_update(
 	}
 
 	fcg_index_shift = fcg_module_info->fcg_index_shift;
+
 	for (i = 0, j = 0; i < fcg_config->num_ch_ctx; i++) {
 		if (j >= fcg_module_info->max_reg_val_pair_size) {
 			CAM_ERR(CAM_SFE, "reg_val_pair %d exceeds the array limit %u",
 				j, fcg_module_info->max_reg_val_pair_size);
 			rc = -ENOMEM;
-			goto kfree;
+			goto free_mem;
 		}
 
 		fcg_ch_ctx = &fcg_config->ch_ctx_fcg_configs[i];
 		if (!fcg_ch_ctx) {
 			CAM_ERR(CAM_SFE, "Failed in FCG channel/context dereference");
 			rc = -EINVAL;
-			goto kfree;
+			goto free_mem;
 		}
 
 		fcg_pr = &fcg_ch_ctx->predicted_fcg_configs[
@@ -1242,7 +1249,7 @@ static int cam_sfe_top_apply_fcg_update(
 				CAM_ERR(CAM_SFE, "Unsupported channel id: 0x%x",
 					fcg_ch_ctx->fcg_ch_ctx_id);
 				rc = -EINVAL;
-				goto kfree;
+				goto free_mem;
 			}
 		}
 
@@ -1282,7 +1289,7 @@ static int cam_sfe_top_apply_fcg_update(
 				CAM_ERR(CAM_SFE, "Unsupported channel id: 0x%x",
 					fcg_ch_ctx->fcg_ch_ctx_id);
 				rc = -EINVAL;
-				goto kfree;
+				goto free_mem;
 			}
 		}
 	}
@@ -1298,7 +1305,7 @@ static int cam_sfe_top_apply_fcg_update(
 				"Failed! Buf size:%d is wrong, expected size: %d",
 				fcg_update->cmd_size, size * 4);
 			rc = -ENOMEM;
-			goto kfree;
+			goto free_mem;
 		}
 
 		cdm_util_ops->cdm_write_regrandom(
@@ -1308,7 +1315,7 @@ static int cam_sfe_top_apply_fcg_update(
 		CAM_WARN(CAM_SFE, "No reg val pairs");
 	}
 
-kfree:
+free_mem:
 	kfree(reg_val_pair);
 	return rc;
 }
@@ -1368,7 +1375,7 @@ static int cam_sfe_top_fcg_config(
 	int rc;
 
 	if (arg_size != sizeof(struct cam_isp_hw_fcg_cmd)) {
-		CAM_ERR(CAM_SFE, "Invalid cmd size, arg_size: %d, expected size: %d",
+		CAM_ERR(CAM_SFE, "Invalid cmd size, arg_size: %u, expected size: %u",
 			arg_size, sizeof(struct cam_isp_hw_fcg_cmd));
 		return -EINVAL;
 	}

+ 17 - 10
drivers/cam_isp/isp_hw_mgr/isp_hw/vfe_hw/vfe_top/cam_vfe_top_ver4.c

@@ -1117,7 +1117,7 @@ static int cam_vfe_top_apply_fcg_update(
 	uint32_t                                        num_regval_pairs = 0;
 	int                                             rc = 0, i, j = 0;
 
-	if (!top_priv || (fcg_update->prediction_idx == 0)) {
+	if (!top_priv || !fcg_update || (fcg_update->prediction_idx == 0)) {
 		CAM_ERR(CAM_ISP, "Invalid args");
 		return -EINVAL;
 	}
@@ -1135,6 +1135,12 @@ static int cam_vfe_top_apply_fcg_update(
 		return -EINVAL;
 	}
 
+	if (fcg_config->num_ch_ctx > CAM_ISP_MAX_FCG_CH_CTXS) {
+		CAM_ERR(CAM_SFE, "out of bounds %d",
+			fcg_config->num_ch_ctx);
+		return -EINVAL;
+	}
+
 	reg_val_pair = kcalloc(fcg_module_info->max_reg_val_pair_size, sizeof(uint32_t),
 		GFP_KERNEL);
 	if (!reg_val_pair) {
@@ -1143,19 +1149,20 @@ static int cam_vfe_top_apply_fcg_update(
 	}
 
 	fcg_index_shift = fcg_module_info->fcg_index_shift;
+
 	for (i = 0, j = 0; i < fcg_config->num_ch_ctx; i++) {
 		if (j >= fcg_module_info->max_reg_val_pair_size) {
 			CAM_ERR(CAM_ISP, "reg_val_pair %d exceeds the array limit %u",
 				j, fcg_module_info->max_reg_val_pair_size);
 			rc = -ENOMEM;
-			goto kfree;
+			goto free_mem;
 		}
 
 		fcg_ch_ctx = &fcg_config->ch_ctx_fcg_configs[i];
 		if (!fcg_ch_ctx) {
 			CAM_ERR(CAM_ISP, "Failed in FCG channel/context dereference");
 			rc = -EINVAL;
-			goto kfree;
+			goto free_mem;
 		}
 
 		fcg_pr = &fcg_ch_ctx->predicted_fcg_configs[
@@ -1200,7 +1207,7 @@ static int cam_vfe_top_apply_fcg_update(
 						"No support for multi context for FCG on ch_ctx_id: 0x%x",
 						fcg_ch_ctx->fcg_ch_ctx_id);
 					rc = -EINVAL;
-					goto kfree;
+					goto free_mem;
 				}
 
 				CAM_VFE_ADD_REG_VAL_PAIR(reg_val_pair, j,
@@ -1233,7 +1240,7 @@ static int cam_vfe_top_apply_fcg_update(
 				CAM_ERR(CAM_ISP, "Unsupported ch_ctx_id: 0x%x",
 					fcg_ch_ctx->fcg_ch_ctx_id);
 				rc = -EINVAL;
-				goto kfree;
+				goto free_mem;
 			}
 		}
 	}
@@ -1249,7 +1256,7 @@ static int cam_vfe_top_apply_fcg_update(
 				"Failed! Buf size:%d is wrong, expected size: %d",
 				fcg_update->cmd_size, size * 4);
 			rc = -ENOMEM;
-			goto kfree;
+			goto free_mem;
 		}
 
 		cdm_util_ops->cdm_write_regrandom(
@@ -1259,7 +1266,7 @@ static int cam_vfe_top_apply_fcg_update(
 		CAM_WARN(CAM_ISP, "No reg val pairs");
 	}
 
-kfree:
+free_mem:
 	kfree(reg_val_pair);
 	return rc;
 }
@@ -1320,7 +1327,7 @@ static int cam_vfe_top_fcg_config(
 	int rc;
 
 	if (arg_size != sizeof(struct cam_isp_hw_fcg_cmd)) {
-		CAM_ERR(CAM_ISP, "Invalid cmd size, arg_size: %d, expected size: %d",
+		CAM_ERR(CAM_ISP, "Invalid cmd size, arg_size: %u, expected size: %u",
 			arg_size, sizeof(struct cam_isp_hw_fcg_cmd));
 		return -EINVAL;
 	}
@@ -1358,8 +1365,8 @@ int cam_vfe_top_ver4_process_cmd(void *device_priv, uint32_t cmd_type,
 {
 	int rc = 0;
 	struct cam_vfe_top_ver4_priv            *top_priv;
-	struct cam_hw_soc_info                  *soc_info = NULL;
-	struct cam_vfe_soc_private              *soc_private = NULL;
+	struct cam_hw_soc_info                  *soc_info;
+	struct cam_vfe_soc_private              *soc_private;
 
 	if (!device_priv || !cmd_args) {
 		CAM_ERR(CAM_ISP, "Error, Invalid arguments");