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 <quic_smalke@quicinc.com>
This commit is contained in:
Shivakumar Malke 2023-02-21 12:12:37 +05:30
commit d7eae61ec4

View file

@ -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 <linux/module.h>
@ -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);