Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c128e5ae authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: memmgr: Avoid TOCTOU buffer access on multiple use of same fd"

parents a95635ac bc5a4006
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -583,6 +583,7 @@ static int cam_mem_util_map_hw_va(uint32_t flags,
	int32_t *mmu_hdls,
	int32_t num_hdls,
	int fd,
	struct dma_buf *dmabuf,
	dma_addr_t *hw_vaddr,
	size_t *len,
	enum cam_smmu_region_id region)
@@ -604,6 +605,7 @@ static int cam_mem_util_map_hw_va(uint32_t flags,
		for (i = 0; i < num_hdls; i++) {
			rc = cam_smmu_map_stage2_iova(mmu_hdls[i],
				fd,
				dmabuf,
				dir,
				hw_vaddr,
				len);
@@ -619,6 +621,7 @@ static int cam_mem_util_map_hw_va(uint32_t flags,
		for (i = 0; i < num_hdls; i++) {
			rc = cam_smmu_map_user_iova(mmu_hdls[i],
				fd,
				dmabuf,
				dir,
				(dma_addr_t *)hw_vaddr,
				len,
@@ -713,6 +716,7 @@ int cam_mem_mgr_alloc_and_map(struct cam_mem_mgr_alloc_cmd *cmd)
			cmd->mmu_hdls,
			cmd->num_hdl,
			fd,
			dmabuf,
			&hw_vaddr,
			&len,
			region);
@@ -815,6 +819,7 @@ int cam_mem_mgr_map(struct cam_mem_mgr_map_cmd *cmd)
			cmd->mmu_hdls,
			cmd->num_hdl,
			cmd->fd,
			dmabuf,
			&hw_vaddr,
			&len,
			CAM_SMMU_REGION_IO);
@@ -1052,8 +1057,6 @@ static int cam_mem_util_unmap(int32_t idx,
		if (cam_mem_util_unmap_hw_va(idx, region, client))
			CAM_ERR(CAM_MEM, "Failed, dmabuf=%pK",
				tbl.bufq[idx].dma_buf);
		if (client == CAM_SMMU_MAPPING_KERNEL)
			tbl.bufq[idx].dma_buf = NULL;
	}

	mutex_lock(&tbl.bufq[idx].q_lock);
@@ -1069,7 +1072,6 @@ static int cam_mem_util_unmap(int32_t idx,
		tbl.bufq[idx].is_imported,
		tbl.bufq[idx].dma_buf);

	if (tbl.bufq[idx].dma_buf)
	dma_buf_put(tbl.bufq[idx].dma_buf);

	tbl.bufq[idx].fd = -1;
+12 −30
Original line number Diff line number Diff line
@@ -226,7 +226,8 @@ static struct cam_dma_buff_info *cam_smmu_find_mapping_by_virt_address(int idx,

static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
	enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr,
	size_t *len_ptr, enum cam_smmu_region_id region_id);
	size_t *len_ptr, enum cam_smmu_region_id region_id,
	struct dma_buf *buf);

static int cam_smmu_map_kernel_buffer_and_add_to_list(int idx,
	struct dma_buf *buf, enum dma_data_direction dma_dir,
@@ -1704,7 +1705,7 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf,
	if (IS_ERR_OR_NULL(attach)) {
		rc = PTR_ERR(attach);
		CAM_ERR(CAM_SMMU, "Error: dma buf attach failed");
		goto err_put;
		goto err_out;
	}

	if (region_id == CAM_SMMU_REGION_SHARED) {
@@ -1830,8 +1831,6 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf,
	dma_buf_unmap_attachment(attach, table, dma_dir);
err_detach:
	dma_buf_detach(buf, attach);
err_put:
	dma_buf_put(buf);
err_out:
	return rc;
}
@@ -1839,14 +1838,11 @@ static int cam_smmu_map_buffer_validate(struct dma_buf *buf,

static int cam_smmu_map_buffer_and_add_to_list(int idx, int ion_fd,
	 enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr,
	 size_t *len_ptr, enum cam_smmu_region_id region_id)
	 size_t *len_ptr, enum cam_smmu_region_id region_id,
	 struct dma_buf *buf)
{
	int rc = -1;
	struct cam_dma_buff_info *mapping_info = NULL;
	struct dma_buf *buf = NULL;

	/* returns the dma_buf structure related to an fd */
	buf = dma_buf_get(ion_fd);

	rc = cam_smmu_map_buffer_validate(buf, idx, dma_dir, paddr_ptr, len_ptr,
		region_id, &mapping_info);
@@ -1942,7 +1938,6 @@ static int cam_smmu_unmap_buf_and_remove_from_list(
	dma_buf_unmap_attachment(mapping_info->attach,
		mapping_info->table, mapping_info->dir);
	dma_buf_detach(mapping_info->buf, mapping_info->attach);
	dma_buf_put(mapping_info->buf);

	mapping_info->buf = NULL;

@@ -2410,10 +2405,9 @@ int cam_smmu_put_scratch_iova(int handle,

static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
		 enum dma_data_direction dma_dir, dma_addr_t *paddr_ptr,
		 size_t *len_ptr)
		 size_t *len_ptr, struct dma_buf *dmabuf)
{
	int rc = 0;
	struct dma_buf *dmabuf = NULL;
	struct dma_buf_attachment *attach = NULL;
	struct sg_table *table = NULL;
	struct cam_sec_buff_info *mapping_info;
@@ -2422,15 +2416,6 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
	*paddr_ptr = (dma_addr_t)NULL;
	*len_ptr = (size_t)0;

	dmabuf = dma_buf_get(ion_fd);
	if (IS_ERR_OR_NULL((void *)(dmabuf))) {
		CAM_ERR(CAM_SMMU,
			"Error: dma buf get failed, idx=%d, ion_fd=%d",
			idx, ion_fd);
		rc = PTR_ERR(dmabuf);
		goto err_out;
	}

	/*
	 * ion_phys() is deprecated. call dma_buf_attach() and
	 * dma_buf_map_attachment() to get the buffer's physical
@@ -2442,7 +2427,7 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
			"Error: dma buf attach failed, idx=%d, ion_fd=%d",
			idx, ion_fd);
		rc = PTR_ERR(attach);
		goto err_put;
		goto err_out;
	}

	attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
@@ -2486,14 +2471,12 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
	dma_buf_unmap_attachment(attach, table, dma_dir);
err_detach:
	dma_buf_detach(dmabuf, attach);
err_put:
	dma_buf_put(dmabuf);
err_out:
	return rc;
}

int cam_smmu_map_stage2_iova(int handle,
		int ion_fd, enum cam_smmu_map_dir dir,
int cam_smmu_map_stage2_iova(int handle, int ion_fd,
		struct dma_buf *dmabuf, enum cam_smmu_map_dir dir,
		dma_addr_t *paddr_ptr, size_t *len_ptr)
{
	int idx, rc;
@@ -2553,7 +2536,7 @@ int cam_smmu_map_stage2_iova(int handle,
		goto get_addr_end;
	}
	rc = cam_smmu_map_stage2_buffer_and_add_to_list(idx, ion_fd, dma_dir,
			paddr_ptr, len_ptr);
			paddr_ptr, len_ptr, dmabuf);
	if (rc < 0) {
		CAM_ERR(CAM_SMMU,
			"Error: mapping or add list fail, idx=%d, handle=%d, fd=%d, rc=%d",
@@ -2575,7 +2558,6 @@ static int cam_smmu_secure_unmap_buf_and_remove_from_list(
		CAM_ERR(CAM_SMMU, "Error: List doesn't exist");
		return -EINVAL;
	}
	dma_buf_put(mapping_info->buf);
	list_del_init(&mapping_info->list);

	CAM_DBG(CAM_SMMU, "unmap fd: %d, idx : %d", mapping_info->ion_fd, idx);
@@ -2688,7 +2670,7 @@ static int cam_smmu_map_iova_validate_params(int handle,
	return rc;
}

int cam_smmu_map_user_iova(int handle, int ion_fd,
int cam_smmu_map_user_iova(int handle, int ion_fd, struct dma_buf *dmabuf,
	enum cam_smmu_map_dir dir, dma_addr_t *paddr_ptr,
	size_t *len_ptr, enum cam_smmu_region_id region_id)
{
@@ -2740,7 +2722,7 @@ int cam_smmu_map_user_iova(int handle, int ion_fd,
	}

	rc = cam_smmu_map_buffer_and_add_to_list(idx, ion_fd, dma_dir,
			paddr_ptr, len_ptr, region_id);
			paddr_ptr, len_ptr, region_id, dmabuf);
	if (rc < 0)
		CAM_ERR(CAM_SMMU,
			"mapping or add list fail, idx=%d, fd=%d, region=%d, rc=%d",
+5 −5
Original line number Diff line number Diff line
@@ -115,8 +115,8 @@ int cam_smmu_ops(int handle, enum cam_smmu_ops_param op);
 * @len_ptr     : Length of buffer mapped returned by CAM SMMU driver.
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_map_user_iova(int handle,
	int ion_fd, enum cam_smmu_map_dir dir,
int cam_smmu_map_user_iova(int handle, int ion_fd,
	struct dma_buf *dmabuf, enum cam_smmu_map_dir dir,
	dma_addr_t *dma_addr, size_t *len_ptr,
	enum cam_smmu_region_id region_id);

@@ -291,9 +291,9 @@ int cam_smmu_put_iova(int handle, int ion_fd);
 *
 * @return Status of operation. Negative in case of error. Zero otherwise.
 */
int cam_smmu_map_stage2_iova(int handle,
	int ion_fd, enum cam_smmu_map_dir dir, dma_addr_t *dma_addr,
	size_t *len_ptr);
int cam_smmu_map_stage2_iova(int handle, int ion_fd,
	struct dma_buf *dmabuf, enum cam_smmu_map_dir dir,
	dma_addr_t *dma_addr, size_t *len_ptr);

/**
 * @brief Unmaps secure memopry for SMMU handle