Sfoglia il codice sorgente

msm: camera: smmu: Use get_file api to increase ref count

In rare scenarios, FD is getting released by userspace
before incrementing the ref count. We see failure in
dma_buf_get API as FD is released but we are still
tying to decrement ref count in case of dma
buf get failure.

We are seeing use-after-free as the buffer is released.

This fix includes get_file API to increment ref count
before dma_buf_fd.

CRs-Fixed: 3156174
Change-Id: Ie9588ec10e65cbb8fa155badda4f3e5fb81c0525
Signed-off-by: Chandan Kumar Jha <[email protected]>
Chandan Kumar Jha 3 anni fa
parent
commit
e542dd7c3e
1 ha cambiato i file con 7 aggiunte e 13 eliminazioni
  1. 7 13
      drivers/cam_req_mgr/cam_mem_mgr.c

+ 7 - 13
drivers/cam_req_mgr/cam_mem_mgr.c

@@ -763,7 +763,6 @@ static int cam_mem_util_buffer_alloc(size_t len, uint32_t flags,
 	unsigned long *i_ino)
 {
 	int rc;
-	struct dma_buf *temp_dmabuf = NULL;
 
 	rc = cam_mem_util_get_dma_buf(len, flags, dmabuf, i_ino);
 	if (rc) {
@@ -773,6 +772,13 @@ static int cam_mem_util_buffer_alloc(size_t len, uint32_t flags,
 		return rc;
 	}
 
+	/*
+	 * increment the ref count so that ref count becomes 2 here
+	 * when we close fd, refcount becomes 1 and when we do
+	 * dmap_put_buf, ref count becomes 0 and memory will be freed.
+	 */
+	get_dma_buf(*dmabuf);
+
 	*fd = dma_buf_fd(*dmabuf, O_CLOEXEC);
 	if (*fd < 0) {
 		CAM_ERR(CAM_MEM, "get fd fail, *fd=%d", *fd);
@@ -783,18 +789,6 @@ static int cam_mem_util_buffer_alloc(size_t len, uint32_t flags,
 	CAM_DBG(CAM_MEM, "Alloc success : len=%zu, *dmabuf=%pK, fd=%d, i_ino=%lu",
 		len, *dmabuf, *fd, *i_ino);
 
-	/*
-	 * increment the ref count so that ref count becomes 2 here
-	 * when we close fd, refcount becomes 1 and when we do
-	 * dmap_put_buf, ref count becomes 0 and memory will be freed.
-	 */
-	temp_dmabuf = dma_buf_get(*fd);
-	if (IS_ERR_OR_NULL(temp_dmabuf)) {
-		rc = PTR_ERR(temp_dmabuf);
-		CAM_ERR(CAM_MEM, "dma_buf_get failed, *fd=%d, i_ino=%lu, rc=%d", *fd, *i_ino, rc);
-		goto put_buf;
-	}
-
 	return rc;
 
 put_buf: