Linux PCI subsystem development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Koichiro Den" <den@valinux.co.jp>
Cc: dmaengine@vger.kernel.org, Frank.Li@kernel.org, vkoul@kernel.org,
	linux-pci@vger.kernel.org
Subject: Re: [PATCH v7 09/10] PCI: endpoint: Add DMA endpoint function
Date: Thu, 13 Aug 2026 06:53:58 +0000	[thread overview]
Message-ID: <20260813065358.927011F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260813063757.3131865-10-den@valinux.co.jp>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] Missing `.remove` callback in the EPF driver allows Use-After-Free upon manual driver unbind.
- [High] TOCTOU race in ConfigFS attributes allows bypassing bound state checks, leading to heap buffer overflows.
- [Medium] Mixing goto-based error handling with scope-based `__free()` cleanup in the same function.
--

--- Patch [9]: [PATCH v7 09/10] PCI: endpoint: Add DMA endpoint function ---
commit 59168807cdf2645897d81a698bfcd8a7744d66f2
Author: Koichiro Den <den@valinux.co.jp>
Subject: PCI: endpoint: Add DMA endpoint function

Add pci-epf-dma, an endpoint function that exposes selected
endpoint-integrated DMA channels as a separate PCI DMA controller
function.

> diff --git a/drivers/pci/endpoint/functions/pci-epf-dma.c b/drivers/pci/endpoint/functions/pci-epf-dma.c
> new file mode 100644
> index 0000000000000..7e1c3e184a06b
> --- /dev/null
> +++ b/drivers/pci/endpoint/functions/pci-epf-dma.c
[ ... ]
> +static int pci_epf_dma_collect_resources(struct pci_epf_dma *epf_dma)
> +{
> +	const struct pci_epc_aux_resource *ep_to_rc_aux_chan[EDMA_MAX_WR_CH] = {};
> +	const struct pci_epc_aux_resource *rc_to_ep_aux_chan[EDMA_MAX_RD_CH] = {};
> +	const struct pci_epc_aux_resource *ep_to_rc_desc[EDMA_MAX_WR_CH] = {};
> +	const struct pci_epc_aux_resource *rc_to_ep_desc[EDMA_MAX_RD_CH] = {};
> +	const struct pci_epc_aux_resource *ctrl = NULL;
> +	struct pci_epf *epf = epf_dma->epf;
> +	struct pci_epc *epc = epf->epc;
> +	struct device *dev = &epf->dev;
> +	int count, i, ret;
> +
> +	count = pci_epc_get_aux_resources_count(epc, epf->func_no,
> +						epf->vfunc_no);
> +	if (count <= 0)
> +		return count ?: -ENODEV;
> +
> +	struct pci_epc_aux_resource *res __free(kfree) =
> +						kzalloc_objs(*res, count);

[Severity: Medium]
Does this code mix goto-based error handling and scope-based cleanup in the
same function?

The res variable uses __free(kfree) for cleanup, but later failures jump to
a goto label instead of returning directly:

	for (i = 0; i < epf_dma->wr_chans; i++) {
		ret = pci_epf_dma_claim_channel(epf_dma, ep_to_rc_aux_chan[i],
						&epf_dma->ep_to_rc_chan[i]);
		if (ret)
			goto err_release_channels;
	}

[ ... ]
> +static int pci_epf_dma_build_metadata(struct pci_epf_dma *epf_dma)
> +{
> +	const struct pci_epf_dma_bar_map *ctrl_map;
> +	u16 entry_size = PCI_EP_DMA_METADATA_CH_ENTRY_SIZE;
> +	u16 wr_table, rd_table, total_len;
> +	__le32 *metadata = epf_dma->metadata_addr;
> +	unsigned int i;
> +	int ret;
> +
> +	if (!metadata)
> +		return -EINVAL;
> +
> +	ctrl_map = pci_epf_dma_find_map(epf_dma, epf_dma->ctrl);
> +	if (!ctrl_map)
> +		return -EINVAL;
> +	if (epf_dma->wr_chans > FIELD_MAX(PCI_EP_DMA_METADATA_CTRL_WR_CH_COUNT) ||
> +	    epf_dma->rd_chans > FIELD_MAX(PCI_EP_DMA_METADATA_CTRL_RD_CH_COUNT) ||
> +	    entry_size > FIELD_MAX(PCI_EP_DMA_METADATA_CTRL_CH_ENTRY_SIZE) ||
> +	    ctrl_map->res->size > U32_MAX)
> +		return -EOVERFLOW;
> +
> +	wr_table = epf_dma->wr_chans ? PCI_EP_DMA_METADATA_HDR_LEN : 0;
> +	rd_table = epf_dma->rd_chans ?
> +		   PCI_EP_DMA_METADATA_HDR_LEN + epf_dma->wr_chans * entry_size : 0;
> +	total_len = PCI_EP_DMA_METADATA_HDR_LEN +
> +		    (epf_dma->wr_chans + epf_dma->rd_chans) * entry_size;
> +
> +	memset(metadata, 0, total_len);

[Severity: High]
Can a concurrent write to the configfs attributes cause an out-of-bounds
memset() here?

During the binding process (pci_epf_dma_bind), pci_epf_dma_build_layout()
allocates space based on the current wr_chans. However, the store
function for the attribute checks epf_dma->epf->epc without holding a lock:

static ssize_t pci_epf_dma_wr_chans_store(...)
{
	...
	if (epf_dma->epf->epc)
		return -EOPNOTSUPP;
	...
	epf_dma->wr_chans = val;
	...
}

Could this allow wr_chans to increase after the space is allocated but
before total_len is calculated for this memset?

[ ... ]
> +static struct pci_epf_driver pci_epf_dma_driver = {
> +	.driver.name	= "pci_epf_dma",
> +	.probe		= pci_epf_dma_probe,
> +	.id_table	= pci_epf_dma_ids,
> +	.ops		= &pci_epf_dma_ops,
> +	.owner		= THIS_MODULE,
> +};

[Severity: Critical]
If a user manually unbinds the driver via sysfs, does the lack of a .remove
callback lead to a use-after-free?

Because there is no .remove callback, the unbind operation appears to free
the epf_dma structure via devres cleanup, but leaves the epf->event_ops
pointer populated and the map_work delayed work still pending.

Could an in-flight map_work execution or a subsequent EPC link event try to
dereference the freed epf_dma memory?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260813063757.3131865-1-den@valinux.co.jp?part=9

  reply	other threads:[~2026-08-13  6:53 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-13  6:37 [PATCH v7 00/10] PCI: endpoint: Add PCI DMA endpoint function Koichiro Den
2026-08-13  6:37 ` [PATCH v7 01/10] dmaengine: Allow drivers to assign static channel IDs Koichiro Den
2026-08-13  6:51   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 02/10] PCI: endpoint: Define endpoint DMA BAR metadata format Koichiro Den
2026-08-13  6:40   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 03/10] PCI: endpoint: Add DMA auxiliary resource metadata Koichiro Den
2026-08-13  6:41   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 04/10] PCI: endpoint: Add API to delegate EPC DMA channels to the host Koichiro Den
2026-08-13  6:46   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 05/10] dmaengine: dw-edma: Add channel delegation helpers Koichiro Den
2026-08-13  6:50   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 06/10] PCI: dwc: Implement endpoint DMA channel delegation Koichiro Den
2026-08-13  6:47   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 07/10] PCI: dwc: Expose endpoint DMA resources Koichiro Den
2026-08-13  6:45   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 08/10] dmaengine: dw-edma-pcie: Discover endpoint DMA metadata Koichiro Den
2026-08-13  6:50   ` sashiko-bot
2026-08-13  6:37 ` [PATCH v7 09/10] PCI: endpoint: Add DMA endpoint function Koichiro Den
2026-08-13  6:53   ` sashiko-bot [this message]
2026-08-13  6:37 ` [PATCH v7 10/10] Documentation: PCI: Add PCI DMA endpoint function documentation Koichiro Den
2026-08-13  6:46   ` sashiko-bot
2026-08-13 11:46 ` [PATCH v7 00/10] PCI: endpoint: Add PCI DMA endpoint function Niklas Cassel

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=20260813065358.927011F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=Frank.Li@kernel.org \
    --cc=den@valinux.co.jp \
    --cc=dmaengine@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=vkoul@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox