summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShivakumar Malke <quic_smalke@quicinc.com>2023-01-19 17:24:44 +0530
committerNick Chung <nickchung@google.com>2023-08-18 06:54:29 +0000
commitdf7e074714a97b48cf58ded79b46cf1e39e3a71e (patch)
treefea395d74db433be4a056cfcbc8cf018d665aef7
parent2577e90e94a0d0f32804e18f966aeeec0149be20 (diff)
downloadcamera-kernel-df7e074714a97b48cf58ded79b46cf1e39e3a71e.tar.gz
msm: camera: smmu: Use get_file to increase ref count
Due to race condition, fd pointing to a particular dma buf is released by userspace before incrementing ref count and hence freed that dma buf. When the call returns it still uses the freed dma buf causing use-after-free. This fix includes get_file API to increment ref count before dma_buf_fd. Bug: 258533280 Test: CTS, GCA CRs-Fixed: 3341070 Change-Id: I8ebc37b4ceb5f8691bbbb3d26b8b64878d832fbe Signed-off-by: Shivakumar Malke <quic_smalke@quicinc.com> Signed-off-by: Nick Chung <nickchung@google.com>
-rw-r--r--drivers/cam_req_mgr/cam_mem_mgr.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c
index 77622e2..d106741 100644
--- a/drivers/cam_req_mgr/cam_mem_mgr.c
+++ b/drivers/cam_req_mgr/cam_mem_mgr.c
@@ -402,7 +402,6 @@ static int cam_mem_util_get_dma_buf_fd(size_t len,
struct dma_buf **buf,
int *fd)
{
- struct dma_buf *dmabuf = NULL;
int rc = 0;
struct timespec64 ts1, ts2;
long microsec = 0;
@@ -418,23 +417,18 @@ static int cam_mem_util_get_dma_buf_fd(size_t len,
*buf = ion_alloc(len, heap_id_mask, flags);
if (IS_ERR_OR_NULL(*buf))
return -ENOMEM;
-
- *fd = dma_buf_fd(*buf, O_CLOEXEC);
- if (*fd < 0) {
- CAM_ERR(CAM_MEM, "get fd fail, *fd=%d", *fd);
- rc = -EINVAL;
- goto get_fd_fail;
- }
-
/*
* 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.
*/
- dmabuf = dma_buf_get(*fd);
- if (IS_ERR_OR_NULL(dmabuf)) {
- CAM_ERR(CAM_MEM, "dma_buf_get failed, *fd=%d", *fd);
+ get_dma_buf(*buf);
+
+ *fd = dma_buf_fd(*buf, O_CLOEXEC);
+ if (*fd < 0) {
+ CAM_ERR(CAM_MEM, "get fd fail, *fd=%d", *fd);
rc = -EINVAL;
+ goto get_fd_fail;
}
if (tbl.alloc_profile_enable) {