Browse Source

msm: camera: common: Add validation check for cpu buffers before accessing

Add validation check before accessing the packets and configs from
the buffers.

CRs-Fixed: 2360223, 2416463
Change-Id: I9a09bc7064fd7e7914f91576542181c301db926d
Signed-off-by: Abhilash Kumar <[email protected]>
Signed-off-by: Mukund Madhusudan Atre <[email protected]>
Abhilash Kumar 6 years ago
parent
commit
3ef8ba0db6

+ 11 - 0
drivers/cam_cdm/cam_cdm_hw_core.c

@@ -473,6 +473,17 @@ int cam_hw_cdm_submit_bl(struct cam_hw_info *cdm_hw,
 
 		if ((!rc) && (hw_vaddr_ptr) && (len) &&
 			(len >= cdm_cmd->cmd[i].offset)) {
+
+			if ((len - cdm_cmd->cmd[i].offset) <
+				cdm_cmd->cmd[i].len) {
+				CAM_ERR(CAM_CDM,
+					"Not enough buffer cmd offset: %u cmd length: %u",
+					cdm_cmd->cmd[i].offset,
+					cdm_cmd->cmd[i].len);
+				rc = -EINVAL;
+				break;
+			}
+
 			CAM_DBG(CAM_CDM, "Got the HW VA");
 			if (core->bl_tag >=
 				(CAM_CDM_HWFIFO_SIZE - 1))

+ 11 - 1
drivers/cam_fd/fd_hw_mgr/cam_fd_hw_mgr.c

@@ -582,13 +582,23 @@ static int cam_fd_mgr_util_prepare_io_buf_info(int32_t iommu_hdl,
 					iommu_hdl, &io_addr[plane], &size);
 				if (rc) {
 					CAM_ERR(CAM_FD,
-						"Invalid io buf %d %d %d %d",
+						"Failed to get io buf %u %u %u %d",
 						io_cfg[i].direction,
 						io_cfg[i].resource_type, plane,
 						rc);
 					return -ENOMEM;
 				}
 
+				if (io_cfg[i].offsets[plane] >= size) {
+					CAM_ERR(CAM_FD,
+						"Invalid io buf %u %u %u %d %u %zu",
+						io_cfg[i].direction,
+						io_cfg[i].resource_type, plane,
+						i, io_cfg[i].offsets[plane],
+						size);
+					return -EINVAL;
+				}
+
 				io_addr[plane] += io_cfg[i].offsets[plane];
 			}
 

+ 18 - 0
drivers/cam_icp/cam_icp_context.c

@@ -129,6 +129,7 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
 	size_t len;
 	uintptr_t packet_addr;
 	struct cam_packet *packet;
+	size_t remain_len = 0;
 
 	rc = cam_mem_get_cpu_buf((int32_t) cmd->packet_handle,
 		&packet_addr, &len);
@@ -139,9 +140,26 @@ static int __cam_icp_config_dev_in_ready(struct cam_context *ctx,
 		return rc;
 	}
 
+	remain_len = len;
+	if ((len < sizeof(struct cam_packet)) ||
+		(cmd->offset >= (len - sizeof(struct cam_packet)))) {
+		CAM_ERR(CAM_CTXT,
+			"Invalid offset, len: %zu cmd offset: %llu sizeof packet: %zu",
+			len, cmd->offset, sizeof(struct cam_packet));
+		return -EINVAL;
+	}
+
+	remain_len -= (size_t)cmd->offset;
 	packet = (struct cam_packet *) ((uint8_t *)packet_addr +
 		(uint32_t)cmd->offset);
 
+	rc = cam_packet_util_validate_packet(packet, remain_len);
+	if (rc) {
+		CAM_ERR(CAM_CTXT, "Invalid packet params, remain length: %zu",
+			remain_len);
+		return rc;
+	}
+
 	if (((packet->header.op_code & 0xff) ==
 		CAM_ICP_OPCODE_IPE_SETTINGS) ||
 		((packet->header.op_code & 0xff) ==

+ 14 - 0
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -3853,6 +3853,9 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
 
 	cmd_desc = (struct cam_cmd_buf_desc *)
 		((uint32_t *) &packet->payload + packet->cmd_buf_offset/4);
+	rc = cam_packet_util_validate_cmd_desc(cmd_desc);
+	if (rc)
+		return rc;
 
 	*fw_cmd_buf_iova_addr = 0;
 	for (i = 0; i < packet->num_cmd_buf; i++, num_cmd_buf++) {
@@ -3868,6 +3871,17 @@ static int cam_icp_mgr_process_cmd_desc(struct cam_icp_hw_mgr *hw_mgr,
 				return rc;
 			}
 			*fw_cmd_buf_iova_addr = addr;
+
+			if ((cmd_desc[i].offset >= len) ||
+				((len - cmd_desc[i].offset) <
+				cmd_desc[i].size)){
+				CAM_ERR(CAM_ICP,
+					"Invalid offset, i: %d offset: %u len: %zu size: %zu",
+					i, cmd_desc[i].offset,
+					len, cmd_desc[i].size);
+				return -EINVAL;
+			}
+
 			*fw_cmd_buf_iova_addr =
 				(*fw_cmd_buf_iova_addr + cmd_desc[i].offset);
 			rc = cam_mem_get_cpu_buf(cmd_desc[i].mem_handle,

+ 8 - 0
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c

@@ -149,6 +149,14 @@ static int cam_jpeg_mgr_process_irq(void *priv, void *data)
 
 	cmd_buf_kaddr = (uint32_t *)kaddr;
 
+	if ((p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset /
+			sizeof(uint32_t)) >= cmd_buf_len) {
+		CAM_ERR(CAM_JPEG, "Invalid offset: %u cmd buf len: %zu",
+			p_cfg_req->hw_cfg_args.hw_update_entries[
+			CAM_JPEG_PARAM].offset, cmd_buf_len);
+		return -EINVAL;
+	}
+
 	cmd_buf_kaddr =
 		(cmd_buf_kaddr +
 		(p_cfg_req->hw_cfg_args.hw_update_entries[CAM_JPEG_PARAM].offset