diff options
author | Shivakumar Malke <quic_smalke@quicinc.com> | 2023-01-19 17:24:44 +0530 |
---|---|---|
committer | Nick Chung <nickchung@google.com> | 2023-08-18 06:54:29 +0000 |
commit | df7e074714a97b48cf58ded79b46cf1e39e3a71e (patch) | |
tree | fea395d74db433be4a056cfcbc8cf018d665aef7 | |
parent | 2577e90e94a0d0f32804e18f966aeeec0149be20 (diff) | |
download | camera-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.c | 18 |
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) { |