All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sultan Alsawaf <sultan@kerneltoast.com>
To: Bin Du <Bin.Du@amd.com>
Cc: mchehab@kernel.org, hverkuil@xs4all.nl,
	laurent.pinchart+renesas@ideasonboard.com,
	bryan.odonoghue@linaro.org, sakari.ailus@linux.intel.com,
	prabhakar.mahadev-lad.rj@bp.renesas.com,
	linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
	pratap.nirujogi@amd.com, benjamin.chan@amd.com, king.li@amd.com,
	gjorgji.rosikopulos@amd.com, Phil.Jawich@amd.com,
	Dominic.Antony@amd.com, Svetoslav.Stoilov@amd.com
Subject: Re: [PATCH v2 6/8] media: platform: amd: isp4 video node and buffers handling added
Date: Wed, 23 Jul 2025 10:55:48 -0700	[thread overview]
Message-ID: <aIEiJL83pOYO8lUJ@sultan-box> (raw)
In-Reply-To: <20250618091959.68293-7-Bin.Du@amd.com>

On Wed, Jun 18, 2025 at 05:19:57PM +0800, Bin Du wrote:
> +static void isp4vid_vb2_detach_dmabuf(void *mem_priv)
> +{
> +	struct isp4vid_vb2_buf *buf = mem_priv;
> +
> +	if (!buf) {
> +		pr_err("fail invalid buf handle\n");
> +		return;
> +	}
> +
> +	struct iosys_map map = IOSYS_MAP_INIT_VADDR(buf->vaddr);

Variable declaration mixed with code, move the variable declaration to the top.

> +
> +	dev_dbg(buf->dev, "detach dmabuf of isp user bo 0x%llx size %ld",
> +		buf->gpu_addr, buf->size);
> +
> +	if (buf->vaddr)
> +		dma_buf_vunmap_unlocked(buf->dbuf, &map);
> +
> +	// put dmabuf for exported ones
> +	dma_buf_put(buf->dbuf);

The dmabuf shouldn't be put from the detach_dmabuf memop. Remove this.

> +
> +	kfree(buf);
> +}

[snip]

> +static void isp4vid_vb2_dmabuf_ops_release(struct dma_buf *dbuf)
> +{
> +	struct isp4vid_vb2_buf *buf = dbuf->priv;
> +
> +	/* drop reference obtained in vb2_isp4vid_get_dmabuf */

s/vb2_isp4vid_get_dmabuf/isp4vid_vb2_get_dmabuf/

> +	if (buf->is_expbuf)
> +		isp4vid_vb2_put(dbuf->priv);
> +	else
> +		dev_dbg(buf->dev, "ignore buf release for implicit case");
> +}

[snip]

> +static struct dma_buf *isp4vid_vb2_get_dmabuf(struct vb2_buffer *vb,
> +					      void *buf_priv,
> +					      unsigned long flags)
> +{
> +	struct isp4vid_vb2_buf *buf = buf_priv;
> +	struct dma_buf *dbuf;
> +
> +	if (buf->dbuf) {
> +		dev_dbg(buf->dev,
> +			"dbuf already created, reuse implicit dbuf\n");
> +		dbuf = buf->dbuf;

The dmabuf is reused here without taking a reference to it. When the get_dmabuf
memop is called by vb2_core_expbuf(), it assumes that a reference to the dmabuf
is acquired. So you need to add `get_dma_buf(dbuf)` here.

> +	} else {
> +		dbuf = isp4vid_get_dmabuf(vb, buf_priv, flags);
> +		dev_dbg(buf->dev, "created new dbuf\n");
> +	}
> +	buf->is_expbuf = true;
> +	refcount_inc(&buf->refcount);
> +
> +	dev_dbg(buf->dev, "buf exported, refcount %d\n",
> +		buf->refcount.refs.counter);
> +
> +	return dbuf;
> +}

[snip]

> +static void *isp4vid_vb2_get_userptr(struct vb2_buffer *vb, struct device *dev,
> +				     unsigned long vaddr, unsigned long size)
> +{
> +	struct isp4vid_vb2_buf *buf;
> +	struct frame_vector *vec;
> +	int n_pages, offset, i;
> +	int ret = -ENOMEM;
> +
> +	buf = kzalloc(sizeof(*buf), GFP_KERNEL);
> +	if (!buf)
> +		return ERR_PTR(-ENOMEM);
> +
> +	buf->dev = dev;
> +	buf->dma_dir = vb->vb2_queue->dma_dir;
> +	offset = vaddr & ~PAGE_MASK;
> +	buf->size = size;
> +	vec = vb2_create_framevec(vaddr, size,
> +				  buf->dma_dir == DMA_FROM_DEVICE ||
> +				  buf->dma_dir == DMA_BIDIRECTIONAL);
> +	if (IS_ERR(vec)) {
> +		kfree(buf);
> +		return vec;
> +	}

You can combine the error handling here with the error path at the bottom of the
function instead of duplicating the `kfree(buf)`.

> +	buf->vec = vec;
> +	n_pages = frame_vector_count(vec);
> +	if (frame_vector_to_pages(vec) < 0) {
> +		unsigned long *nums = frame_vector_pfns(vec);
> +
> +		/*
> +		 * We cannot get page pointers for these pfns. Check memory is
> +		 * physically contiguous and use direct mapping.
> +		 */
> +		for (i = 1; i < n_pages; i++)
> +			if (nums[i - 1] + 1 != nums[i])
> +				goto err_destroy_free;
> +		buf->vaddr = (__force void *)
> +			     ioremap(__pfn_to_phys(nums[0]), size + offset);
> +	} else {
> +		buf->vaddr = vm_map_ram(frame_vector_pages(vec), n_pages, -1);
> +	}
> +
> +	if (!buf->vaddr)
> +		goto err_destroy_free;
> +
> +	buf->vaddr = ((char *)buf->vaddr) + offset;
> +	return buf;
> +
> +err_destroy_free:
> +	vb2_destroy_framevec(vec);
> +	kfree(buf);
> +	return ERR_PTR(ret);
> +}
> +
> +static void isp4vid_vb2_put(void *buf_priv)
> +{
> +	struct isp4vid_vb2_buf *buf = (struct isp4vid_vb2_buf *)buf_priv;
> +	struct amdgpu_bo *bo = (struct amdgpu_bo *)buf->bo;
> +
> +	dev_dbg(buf->dev,
> +		"release isp user bo 0x%llx size %ld refcount %d is_expbuf %d",
> +		buf->gpu_addr, buf->size,
> +		buf->refcount.refs.counter, buf->is_expbuf);
> +
> +	if (refcount_dec_and_test(&buf->refcount)) {
> +		amdgpu_bo_free_isp_user(bo);
> +
> +		// put implicit dmabuf here, detach_dmabuf will not be called

Comment style (use /**/ instead of //).

> +		if (!buf->is_expbuf)
> +			dma_buf_put(buf->dbuf);
> +
> +		vfree(buf->vaddr);
> +		kfree(buf);
> +		buf = NULL;

`buf = NULL;` here is superfluous; you can remove it.

> +	} else {
> +		dev_warn(buf->dev, "ignore buffer free, refcount %u > 0",
> +			 refcount_read(&buf->refcount));

This refcount_read() is a possible use-after-free because `buf` is accessed
after isp4vid_vb2_put() puts its reference to `buf`. So something else could put
the last reference to `buf` and free it after this refcount dec but before the
refcount_read(). Maybe just remove this dev_warn() entirely?

> +	}
> +}
> +
> +static void *isp4vid_vb2_alloc(struct vb2_buffer *vb, struct device *dev,
> +			       unsigned long size)
> +{
> +	struct isp4vid_dev *isp_vdev = vb2_get_drv_priv(vb->vb2_queue);
> +	struct isp4vid_vb2_buf *buf = NULL;
> +	struct amdgpu_bo *bo;
> +	u64 gpu_addr;
> +	u32 ret;
> +
> +	buf = kzalloc(sizeof(*buf), GFP_KERNEL | vb->vb2_queue->gfp_flags);
> +	if (!buf)
> +		return ERR_PTR(-ENOMEM);
> +
> +	buf->dev = dev;
> +	buf->size = size;
> +	buf->vaddr = vmalloc_user(buf->size);
> +	if (!buf->vaddr) {
> +		kfree(buf);
> +		return ERR_PTR(-ENOMEM);
> +	}
> +
> +	buf->dma_dir = vb->vb2_queue->dma_dir;
> +	buf->handler.refcount = &buf->refcount;
> +	buf->handler.put = isp4vid_vb2_put;
> +	buf->handler.arg = buf;

What is buf->handler for? I don't see it used anywhere in the entire patchset; I
can delete `handler` from `struct isp4vid_vb2_buf` along with these lines and it
compiles. 

> +
> +	// get implicit dmabuf

Comment style.

> +	buf->dbuf = isp4vid_get_dmabuf(vb, buf, 0);
> +	if (!buf->dbuf) {
> +		dev_err(dev, "fail to get dmabuf\n");
> +		return ERR_PTR(-EINVAL);
> +	}

Doesn't free `buf` or `buf->vaddr` on error here. Also, comment style.

> +
> +	// create isp user BO and obtain gpu_addr

Comment style.

> +	ret = amdgpu_bo_create_isp_user(isp_vdev->amdgpu_dev, buf->dbuf,
> +					AMDGPU_GEM_DOMAIN_GTT, &bo, &gpu_addr);
> +	if (ret) {
> +		dev_err(dev, "fail to create BO\n");
> +		return ERR_PTR(-EINVAL);
> +	}

Doesn't free `buf` or `buf->vaddr` or put `buf->dbuf` on error here.

> +
> +	buf->bo = (void *)bo;
> +	buf->gpu_addr = gpu_addr;
> +
> +	refcount_set(&buf->refcount, 1);

This discards the refcount inc triggered from amdgpu_bo_create_isp_user() when
it calls get_dma_buf(), leading to a use-after-free. Move this refcount_set()
up, preferably right after vmalloc_user() or right after `buf` is allocated so
there's no risk of this issue occurring again in the future.

> +
> +	dev_dbg(dev, "allocated isp user bo 0x%llx size %ld refcount %d",
> +		buf->gpu_addr, buf->size, buf->refcount.refs.counter);
> +
> +	return buf;
> +}

[snip]

Sultan

  reply	other threads:[~2025-07-23 17:55 UTC|newest]

Thread overview: 98+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-06-18  9:19 [PATCH v2 0/8] Add AMD ISP4 driver Bin Du
2025-06-18  9:19 ` [PATCH v2 1/8] media: platform: amd: Introduce amd isp4 capture driver Bin Du
2025-06-18 15:58   ` Mario Limonciello
2025-06-19  7:46     ` Du, Bin
2025-06-19 13:00       ` Mario Limonciello
2025-06-20  3:08         ` Du, Bin
2025-07-28  5:54   ` Sakari Ailus
2025-07-28  9:00     ` Du, Bin
2025-06-18  9:19 ` [PATCH v2 2/8] media: platform: amd: low level support for isp4 firmware Bin Du
2025-06-18 16:00   ` Mario Limonciello
2025-06-19  7:53     ` Du, Bin
2025-07-28  5:57   ` Sakari Ailus
2025-07-28  9:24     ` Du, Bin
2025-06-18  9:19 ` [PATCH v2 3/8] media: platform: amd: Add helpers to configure isp4 mipi phy Bin Du
2025-07-28  6:33   ` Sakari Ailus
2025-08-05  9:53     ` Du, Bin
2025-08-05 10:53       ` Laurent Pinchart
2025-08-06  9:56         ` Du, Bin
2025-08-05 10:39     ` Laurent Pinchart
2025-08-06  9:45       ` Du, Bin
2025-07-28  7:28   ` Sakari Ailus
2025-07-31  9:31     ` Du, Bin
2025-06-18  9:19 ` [PATCH v2 4/8] media: platform: amd: Add isp4 fw and hw interface Bin Du
2025-06-18 16:17   ` Mario Limonciello
2025-06-19  9:58     ` Du, Bin
2025-06-19 15:11       ` Mario Limonciello
2025-06-20  3:32         ` Du, Bin
2025-07-28  7:23   ` Sakari Ailus
2025-07-29  9:12     ` Du, Bin
2025-08-11 11:46       ` Sakari Ailus
2025-08-11 12:31         ` Laurent Pinchart
2025-08-12  3:36           ` Du, Bin
2025-08-12  7:34             ` Laurent Pinchart
2025-08-12  8:08               ` Du, Bin
2025-08-12  8:20               ` Sakari Ailus
2025-08-12 10:04                 ` Du, Bin
2025-08-12  2:44         ` Du, Bin
2025-06-18  9:19 ` [PATCH v2 5/8] media: platform: amd: isp4 subdev and firmware loading handling added Bin Du
2025-06-18 16:35   ` Mario Limonciello
2025-06-20  9:31     ` Du, Bin
2025-07-06 20:55       ` Mario Limonciello
2025-07-07  6:22         ` Du, Bin
2025-07-25  1:35   ` Sultan Alsawaf
2025-07-25  9:03     ` Du, Bin
2025-06-18  9:19 ` [PATCH v2 6/8] media: platform: amd: isp4 video node and buffers " Bin Du
2025-07-23 17:55   ` Sultan Alsawaf [this message]
2025-07-24  5:14     ` Sultan Alsawaf
2025-07-25  9:05       ` Du, Bin
2025-07-25  9:22     ` Du, Bin
2025-07-26 21:41       ` Sultan Alsawaf
2025-07-26 21:50         ` Sultan Alsawaf
2025-07-29  6:12           ` Du, Bin
2025-07-29  6:08         ` Du, Bin
2025-07-28  7:04   ` Sultan Alsawaf
2025-07-29  7:43     ` Du, Bin
2025-07-31  0:34       ` Sultan Alsawaf
2025-07-31  9:45         ` Du, Bin
2025-08-11  6:02         ` Sultan Alsawaf
2025-08-11  9:05           ` Du, Bin
2025-08-12  5:51             ` Sultan Alsawaf
2025-08-12  6:33               ` Du, Bin
2025-08-13  9:42                 ` Du, Bin
2025-08-14  6:37                   ` Sultan Alsawaf
2025-06-18  9:19 ` [PATCH v2 7/8] media: platform: amd: isp4 debug fs logging and more descriptive errors Bin Du
2025-06-18  9:19 ` [PATCH v2 8/8] Documentation: add documentation of AMD isp 4 driver Bin Du
2025-08-05 11:37   ` Laurent Pinchart
2025-08-12  1:36     ` Du, Bin
2025-08-12 13:42       ` Laurent Pinchart
2025-08-22  2:28         ` Du, Bin
2025-08-20 12:42       ` Sakari Ailus
2025-08-22  2:20         ` Du, Bin
2025-09-22  6:24           ` Sakari Ailus
2025-09-22  9:19             ` Du, Bin
2025-07-23 18:12 ` [PATCH v2 0/8] Add AMD ISP4 driver Sultan Alsawaf
2025-07-25 10:22   ` Du, Bin
2025-07-26 22:31     ` Sultan Alsawaf
2025-07-29  3:32       ` Du, Bin
2025-07-29  7:42         ` Sultan Alsawaf
2025-07-29  7:45           ` Sultan Alsawaf
2025-07-29 10:13             ` Du, Bin
2025-07-30  5:38               ` Sultan Alsawaf
2025-07-30  9:53                 ` Du, Bin
2025-07-31  0:30                   ` Sultan Alsawaf
2025-07-31 10:04                     ` Du, Bin
2025-08-04  3:32                       ` Du, Bin
2025-08-04  4:25                         ` Sultan Alsawaf
2025-08-08  9:11                           ` Du, Bin
2025-08-11  5:49                             ` Sultan Alsawaf
2025-08-11  8:35                               ` Du, Bin
2025-08-11 21:48                                 ` Sultan Alsawaf
2025-08-11 22:17                                   ` Sultan Alsawaf
2025-08-12  2:02                                     ` Du, Bin
2025-08-14  6:53 ` Sultan Alsawaf
2025-08-22  2:23   ` Du, Bin
2025-08-22  3:56     ` Sultan Alsawaf
2025-08-27 10:30       ` Du, Bin
2025-08-28  5:50         ` Sultan Alsawaf
2025-09-02  2:08           ` Du, Bin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aIEiJL83pOYO8lUJ@sultan-box \
    --to=sultan@kerneltoast.com \
    --cc=Bin.Du@amd.com \
    --cc=Dominic.Antony@amd.com \
    --cc=Phil.Jawich@amd.com \
    --cc=Svetoslav.Stoilov@amd.com \
    --cc=benjamin.chan@amd.com \
    --cc=bryan.odonoghue@linaro.org \
    --cc=gjorgji.rosikopulos@amd.com \
    --cc=hverkuil@xs4all.nl \
    --cc=king.li@amd.com \
    --cc=laurent.pinchart+renesas@ideasonboard.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=pratap.nirujogi@amd.com \
    --cc=sakari.ailus@linux.intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.