From d7eae61ec4c7cee29ad2c0117d0f53617df2069b Mon Sep 17 00:00:00 2001 From: Shivakumar Malke Date: Tue, 21 Feb 2023 12:12:37 +0530 Subject: [PATCH] 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. CRs-Fixed: 3341070 Change-Id: I8ebc37b4ceb5f8691bbbb3d26b8b64878d832fbe Signed-off-by: Shivakumar Malke --- drivers/cam_req_mgr/cam_mem_mgr.c | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/drivers/cam_req_mgr/cam_mem_mgr.c b/drivers/cam_req_mgr/cam_mem_mgr.c index 369f6639638f..2cf85ed77136 100644 --- a/drivers/cam_req_mgr/cam_mem_mgr.c +++ b/drivers/cam_req_mgr/cam_mem_mgr.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -438,7 +438,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; @@ -457,6 +456,12 @@ 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; + /* + * 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(*buf); *fd = dma_buf_fd(*buf, O_CLOEXEC); if (*fd < 0) { @@ -465,17 +470,6 @@ static int cam_mem_util_get_dma_buf_fd(size_t len, 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); - rc = -EINVAL; - } - if (tbl.alloc_profile_enable) { CAM_GET_TIMESTAMP(ts2); CAM_GET_TIMESTAMP_DIFF_IN_MICRO(ts1, ts2, microsec);