소스 검색

msm: camera: common: Fixing potential OOB cases

This change validates scratch buffer offset and kmd
cmd buffer offset length to avoid OOB access issues,
This change adds fix to sizeof operater's parameter,
Adds fix to avoid buffer overflow.

CRs-Fixed: 3800787
Change-Id: I619b56e8dc262911b17072a03c103e2986c32ed4
Signed-off-by: Yash Upadhyay <[email protected]>
Yash Upadhyay 1 년 전
부모
커밋
96bbf9473a
2개의 변경된 파일24개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 1
      drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c
  2. 23 0
      drivers/cam_isp/isp_hw_mgr/cam_ife_hw_mgr.c

+ 1 - 1
drivers/cam_icp/icp_hw/icp_hw_mgr/cam_icp_hw_mgr.c

@@ -6573,7 +6573,7 @@ static int cam_icp_mgr_hw_dump(void *hw_priv, void *hw_dump_args)
 	*mgr_addr++ = hw_mgr->icp_booted;
 	*mgr_addr++ = hw_mgr->icp_resumed;
 	*mgr_addr++ = hw_mgr->disable_ubwc_comp;
-	memcpy(mgr_addr, &hw_mgr->dev_info, sizeof(hw_mgr->dev_info));
+	memcpy(mgr_addr, &hw_mgr->dev_info, sizeof(struct cam_icp_hw_device_info));
 	mgr_addr += sizeof(hw_mgr->dev_info);
 	*mgr_addr++ = hw_mgr->icp_pc_flag;
 	*mgr_addr++ = hw_mgr->dev_pc_flag;

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

@@ -8859,6 +8859,15 @@ static int cam_isp_scratch_buf_update_util(
 		return rc;
 	}
 
+	if (buffer_info->offset >= size) {
+		CAM_ERR(CAM_ISP,
+			"Invalid scratch buffer offset:%u size:%u mmu_hdl:%u hdl:%d res_type:0x%x",
+			buffer_info->offset, size, mmu_hdl, buffer_info->mem_handle,
+			buffer_info->resource_type);
+		rc = -EINVAL;
+		return rc;
+	}
+
 	port_info->res_id = buffer_info->resource_type;
 	port_info->io_addr = io_addr + buffer_info->offset;
 	port_info->width = buffer_info->width;
@@ -11785,6 +11794,7 @@ static int cam_ife_mgr_util_insert_frame_header(
 	uint32_t frame_header_iova, padded_bytes = 0;
 	size_t len;
 	struct cam_ife_hw_mgr *hw_mgr = &g_ife_hw_mgr;
+	struct cam_smmu_buffer_tracker  *buf_track_entry;
 
 	mmu_hdl = cam_mem_is_secure_buf(
 			kmd_buf->handle) ?
@@ -11800,6 +11810,19 @@ static int cam_ife_mgr_util_insert_frame_header(
 		return rc;
 	}
 
+	if (kmd_buf->offset >= len) {
+		CAM_ERR(CAM_ISP,
+			"Invalid kmd buffer offset %u",
+			kmd_buf->offset);
+		if (buf_tracker) {
+			buf_track_entry = list_first_entry_or_null(buf_tracker,
+					struct cam_smmu_buffer_tracker, list);
+			cam_smmu_buffer_tracker_buffer_putref(buf_track_entry);
+		}
+		rc = -EINVAL;
+		return rc;
+	}
+
 	/* CDM buffer is within 32-bit address space */
 	frame_header_iova = (uint32_t)iova_addr;
 	frame_header_iova += kmd_buf->offset;