Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e687fa9a authored by Shivakumar Malke's avatar Shivakumar Malke Committed by Gerrit - the friendly Code Review server
Browse files

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: default avatarShivakumar Malke <quic_smalke@quicinc.com>
parent c487910c
Loading
Loading
Loading
Loading
+7 −13
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2016-2020 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>
@@ -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) {