All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Alistair Popple" <apopple@nvidia.com>, dri-devel@lists.freedesktop.org
Cc: intel-xe@lists.freedesktop.org, linux-rdma@vger.kernel.org,
	media-ci@linuxtv.org
Subject: Re: [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type
Date: Mon, 26 Oct 2026 09:00:27 +0000	[thread overview]
Message-ID: <sashiko-outbox-184718@kernel.org> (raw)
In-Reply-To: <20261026053623.202642-16-apopple@nvidia.com>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] vfio/pci: vfio_pci_dma_buf_match_mapping() breaks iopt_map_dmabuf() attach
- [High] vfio/pci: UAF on pdev->p2pdma in vfio_pci_dma_buf_match_mapping()
--

commit 9770a3eb805c4984c35cbfef83d18657c914f9b0
Author: Jason Gunthorpe <jgg@ziepe.ca>

vfio/pci: Change the DMA-buf exporter to use mapping_type

This commit converts the VFIO PCI DMA-buf exporter to implement a
match_mapping() callback offering an SGT P2P mapping type and replaces the
attachment->peer2peer check in vfio_pci_dma_buf_attach(). It also holds a
pci_dev reference in struct vfio_pci_dma_buf for the lifetime of the
dma-buf to pass to DMA_BUF_EMAPPING_SGT_P2P().

> diff --git a/drivers/vfio/pci/vfio_pci_dmabuf.c b/drivers/vfio/pci/vfio_pci_dmabuf.c
> index c16f460c01d68..58e771309c5f6 100644
> --- a/drivers/vfio/pci/vfio_pci_dmabuf.c
> +++ b/drivers/vfio/pci/vfio_pci_dmabuf.c

[ ... ]

> @@ -95,15 +93,31 @@ static void vfio_pci_dma_buf_release(struct dma_buf *dmabuf)
>  		up_write(&priv->vdev->memory_lock);
>  		vfio_device_put_registration(&priv->vdev->vdev);
>  	}
> +	pci_dev_put(priv->pdev);
>  	kfree(priv->phys_vec);
>  	kfree(priv);
>  }
>  
> -static const struct dma_buf_ops vfio_pci_dmabuf_ops = {
> -	.attach = vfio_pci_dma_buf_attach,
> +static const struct dma_buf_mapping_sgt_exp_ops vfio_pci_dma_buf_sgt_ops = {
>  	.map_dma_buf = vfio_pci_dma_buf_map,
>  	.unmap_dma_buf = vfio_pci_dma_buf_unmap,
> +};
> +
> +static int vfio_pci_dma_buf_match_mapping(struct dma_buf_match_args *args)
> +{
> +	struct vfio_pci_dma_buf *priv = args->dmabuf->priv;
> +	struct dma_buf_mapping_match sgt_match[1];
> +
> +	sgt_match[0] = DMA_BUF_EMAPPING_SGT_P2P(&vfio_pci_dma_buf_sgt_ops,
> +						priv->pdev);

[Severity: High]
Does offering only DMA_BUF_EMAPPING_SGT_P2P() here break iommufd mapping of
VFIO PCI dma-bufs via iopt_map_dmabuf()?

When userspace maps a VFIO PCI dma-buf through iommufd, iopt_map_dmabuf()
in drivers/iommu/iommufd/pages.c attaches using iommufd_global_device()
before calling sym_vfio_pci_dma_buf_iommufd_map():

drivers/iommu/iommufd/pages.c:iopt_map_dmabuf()
	attach = dma_buf_dynamic_attach(dmabuf, iommufd_global_device(),
					&iopt_dmabuf_attach_revoke_ops, pages);
	if (IS_ERR(attach))
		return PTR_ERR(attach);
	...
	rc = sym_vfio_pci_dma_buf_iommufd_map(attach, &pages->dmabuf.phys);

where iommufd_global_device() in drivers/iommu/iommufd/main.c returns
iommu_misc_dev.this_device, a miscdevice with no parent pci_dev.

With DMA_BUF_EMAPPING_SGT_P2P(), dma_buf_dynamic_attach() runs:

  dma_buf_mapping_attach()
    -> vfio_pci_dma_buf_match_mapping()
      -> dma_buf_match_mapping()
        -> dma_buf_sgt_match()
          -> pci_p2pdma_distance(priv->pdev, iommufd_global_device(), true)
            -> pci_p2pdma_distance_many()

In drivers/pci/p2pdma.c:pci_p2pdma_distance_many(), find_parent_pci_dev()
returns NULL for iommufd_global_device():

	for (i = 0; i < num_clients; i++) {
		pci_client = find_parent_pci_dev(clients[i]);
		if (!pci_client) {
			if (verbose)
				dev_warn(clients[i],
					 "cannot be used for peer-to-peer DMA as it is not a PCI device\n");
			return -1;
		}

This emits a dev_warn() and returns -1, causing dma_buf_sgt_match() to
return -EOPNOTSUPP and dma_buf_match_mapping() to fail with -EINVAL before
sym_vfio_pci_dma_buf_iommufd_map() can be reached.

> +
> +	return dma_buf_match_mapping(args, sgt_match, ARRAY_SIZE(sgt_match));
> +}

[Severity: High]
Can passing priv->pdev to DMA_BUF_EMAPPING_SGT_P2P() in
vfio_pci_dma_buf_match_mapping() race with driver unbind and trigger a
use-after-free on pdev->p2pdma?

When the VFIO device is closed while the exported dma-buf fd remains open,
vfio_pci_dma_buf_cleanup() revokes the dma-buf and drops the vfio_device
registration reference:

drivers/vfio/pci/vfio_pci_dmabuf.c:vfio_pci_dma_buf_cleanup()
	list_for_each_entry_safe(priv, tmp, &vdev->dmabufs, dmabufs_elm) {
		if (!get_file_active(&priv->dmabuf->file))
			continue;

		list_del_init(&priv->dmabufs_elm);
		priv->vdev = NULL;
		vfio_device_put_registration(&vdev->vdev);
		fput(priv->dmabuf->file);
	}

Once vfio_device_put_registration() drops that reference, nothing pins the
driver binding on priv->pdev (pci_dev_get() only pins struct pci_dev, not
devres). Unbinding vfio-pci runs devres_release_all(), which invokes
pci_p2pdma_release() and frees the devm_kzalloc()-allocated struct
pci_p2pdma:

drivers/pci/p2pdma.c:pci_p2pdma_release()
	/* Flush and disable pci_alloc_p2p_mem() */
	pdev->p2pdma = NULL;
	if (p2pdma->pool)
		synchronize_rcu();
	xa_destroy(&p2pdma->map_types);

Because vfio_pci_core_init_dev() only calls pcim_p2pdma_init() and never
allocates p2pdma->pool via pci_p2pdma_add_resource(), p2pdma->pool is NULL.
As a result, pci_p2pdma_release() skips synchronize_rcu(), immediately
calls xa_destroy(&p2pdma->map_types), and devres frees p2pdma.

Concurrently, if an importer attaches to the open dma-buf fd,
dma_buf_mapping_attach() calls vfio_pci_dma_buf_match_mapping() before
vfio_pci_dma_buf_attach() checks priv->revoked:

  dma_buf_mapping_attach()
    -> vfio_pci_dma_buf_match_mapping()
      -> dma_buf_match_mapping()
        -> dma_buf_sgt_match()
          -> pci_p2pdma_distance()
            -> pci_p2pdma_distance_many()
              -> calc_map_type_and_dist()

In drivers/pci/p2pdma.c:calc_map_type_and_dist():

	rcu_read_lock();
	p2pdma = rcu_dereference(provider->p2pdma);
	if (p2pdma)
		xa_store(&p2pdma->map_types, map_types_idx(client),
			 xa_mk_value(map_type), GFP_ATOMIC);
	rcu_read_unlock();

Without synchronize_rcu() in pci_p2pdma_release(), calc_map_type_and_dist()
can load a non-NULL p2pdma pointer just before pdev->p2pdma is cleared and
call xa_store(&p2pdma->map_types, ...) concurrently with xa_destroy() and
after p2pdma has been freed by devres.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261026053623.202642-1-apopple@nvidia.com?part=15

  reply	other threads:[~2026-10-26  9:00 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-26  5:35 [PATCH 00/26] DMA-buf mapping types Alistair Popple
2026-10-26  5:35 ` [PATCH 01/26] dma-buf: Introduce " Alistair Popple
2026-10-26  7:00   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 02/26] dma-buf: Add the SGT DMA mapping type Alistair Popple
2026-10-26  7:04   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 03/26] dma-buf: Add dma_buf_mapping_attach() Alistair Popple
2026-10-26  7:20   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 04/26] dma-buf: Route SGT related actions through attach->map_type Alistair Popple
2026-10-26  7:29   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 05/26] dma-buf: Let the exporter select mapping type at pin/map Alistair Popple
2026-10-26  7:39   ` sashiko-bot
2026-10-26  8:03   ` Karl Mehltretter
2026-10-27  5:46     ` Alistair Popple
2026-10-26  5:35 ` [PATCH 06/26] dma-buf: Add match set queries for exporter placement decisions Alistair Popple
2026-10-26  7:42   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 07/26] dma-buf: Add dma_buf_mapping_map() returning a type-tagged mapping Alistair Popple
2026-10-26  7:56   ` sashiko-bot
2026-10-26  5:35 ` [PATCH 08/26] dma-buf: Allow single exporter drivers to avoid the match_mapping function Alistair Popple
2026-10-26  7:58   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 09/26] drm: Check the SGT ops for drm_gem_map_dma_buf() Alistair Popple
2026-10-26  8:02   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 10/26] dma-buf: Convert all the simple exporters to use SGT mapping type Alistair Popple
2026-10-26  8:12   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 11/26] drm/vmwgfx: Use match_mapping instead of dummy calls Alistair Popple
2026-10-26  8:13   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 12/26] accel/habanalabs: Use the SGT_P2P mapping type Alistair Popple
2026-10-26  8:18   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 13/26] drm/xe/dma-buf: Use the SGT " Alistair Popple
2026-10-26  8:34   ` sashiko-bot
2026-10-27  4:26     ` Alistair Popple
2026-10-26  5:36 ` [PATCH 14/26] drm/amdgpu: " Alistair Popple
2026-10-26  8:46   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 15/26] vfio/pci: Change the DMA-buf exporter to use mapping_type Alistair Popple
2026-10-26  9:00   ` sashiko-bot [this message]
2026-10-26  5:36 ` [PATCH 16/26] RDMA/uverbs: Use the SGT_P2P mapping type Alistair Popple
2026-10-26  9:16   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 17/26] dma-buf: Update dma_buf_phys_vec_to_sgt() to use the SGT " Alistair Popple
2026-10-26  9:26   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 18/26] iio: buffer: convert " Alistair Popple
2026-10-26  9:28   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 19/26] functionfs: " Alistair Popple
2026-10-26  9:35   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 20/26] dma-buf: Remove unused SGT stuff from the common structures Alistair Popple
2026-10-26  9:39   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 21/26] treewide: Rename dma_buf_map_attachment(_unlocked) to dma_buf_sgt_ Alistair Popple
2026-10-26  9:49   ` sashiko-bot
2026-10-27 12:05   ` Christian König
2026-10-27 12:35     ` Jason Gunthorpe
2026-10-26  5:36 ` [PATCH 22/26] treewide: Rename dma_buf_unmap_attachment(_unlocked) to dma_buf_sgt_* Alistair Popple
2026-10-26  9:56   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 23/26] treewide: Rename dma_buf_attach() to dma_buf_sgt_attach() Alistair Popple
2026-10-26 10:01   ` sashiko-bot
2026-10-27  2:15   ` Karl Mehltretter
2026-10-27  3:42     ` Mikko Perttunen
2026-10-27 12:33       ` Jason Gunthorpe
2026-10-27 13:34         ` Mikko Perttunen
2026-10-27 13:43           ` Christian König
2026-10-27 12:11     ` Christian König
2026-10-27 12:31     ` Jason Gunthorpe
2026-10-27 12:07   ` Christian König
2026-10-27 12:38     ` Jason Gunthorpe
2026-10-27 13:17       ` Christian König
2026-10-27 14:08         ` Jason Gunthorpe
2026-10-27 14:28           ` Christian König
2026-10-27 14:44             ` Jason Gunthorpe
2026-10-27 14:54               ` Christian König
2026-10-26  5:36 ` [PATCH 24/26] treewide: Rename dma_buf_dynamic_attach() to dma_buf_sgt_dynamic_attach() Alistair Popple
2026-10-26 10:13   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 25/26] dma-buf: Add kunit tests for mapping type Alistair Popple
2026-10-26 10:19   ` sashiko-bot
2026-10-26  5:36 ` [PATCH 26/26] dma-buf: Add kunit tests for mapping type selection Alistair Popple
2026-10-26 10:22   ` sashiko-bot

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=sashiko-outbox-184718@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=apopple@nvidia.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=linux-rdma@vger.kernel.org \
    --cc=media-ci@linuxtv.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /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.