All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Pei Xiao" <xiaopei01@kylinos.cn>
Cc: linux-pci@vger.kernel.org
Subject: Re: [PATCH v2] PCI: switchtec: Fix use-after-free in switchtec_pci_remove due to race condition
Date: Thu, 06 Aug 2026 02:37:10 +0000	[thread overview]
Message-ID: <20260806023711.52FA71F000E9@smtp.kernel.org> (raw)
In-Reply-To: <1f52d931ec7a7f5b36837cabf07b36e0463bf182.1785982054.git.xiaopei01@kylinos.cn>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:

Pre-existing issues:
- [High] The delayed work `mrpc_timeout` can be concurrently re-armed by `switchtec_dev_write()` after being cancelled in `stdev_kill()`, leading to UAF of devm-freed MMIO or `stdev`.
- [High] Probe error path bypasses `stdev_kill()`, leading to UAF of `stdev` by active devm-managed IRQs and uncancelled workqueues.
- [High] Missing `dma_rmb()` between reading DMA status and DMA data.
--

--- Patch [1]: [PATCH v2] PCI: switchtec: Fix use-after-free in switchtec_pci_remove due to race condition ---
commit 1cdcc605287dd43ead581c21636460c8793d36f2
Author: Pei Xiao <xiaopei01@kylinos.cn>
Subject: PCI: switchtec: Fix use-after-free in switchtec_pci_remove due to race condition

This commit attempts to fix a use-after-free bug during device removal by
explicitly clearing bus master and freeing IRQs before cancelling workqueues.

> diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
> index 41fc4b5127081..4b0988013c69d 100644
> --- a/drivers/pci/switch/switchtec.c
> +++ b/drivers/pci/switch/switchtec.c
> @@ -1318,6 +1318,13 @@ static void stdev_kill(struct switchtec_dev *stdev)
>  
>  	pci_clear_master(stdev->pdev);
>  
> +	if (stdev->event_irq >= 0)
> +		devm_free_irq(&stdev->pdev->dev, stdev->event_irq, stdev);
> +	if (stdev->dma_mrpc_irq >= 0)
> +		devm_free_irq(&stdev->pdev->dev, stdev->dma_mrpc_irq, stdev);
> +
> +	cancel_work_sync(&stdev->mrpc_work);
> +	cancel_work_sync(&stdev->link_event_work);
>  	cancel_delayed_work_sync(&stdev->mrpc_timeout);
>  
>  	/* Mark the hardware as unavailable and complete all completions */

[Severity: High]
This is a pre-existing issue, but can the delayed work mrpc_timeout be
concurrently re-armed after it is cancelled here?

During device removal, stdev_kill() cancels mrpc_timeout before holding
mrpc_mutex and setting alive = false:

drivers/pci/switch/switchtec.c:stdev_kill() {
	...
	cancel_delayed_work_sync(&stdev->mrpc_timeout);
	scoped_guard (mutex, &stdev->mrpc_mutex) {
		stdev->alive = false;
	...
}

Could userspace concurrently call switchtec_dev_write(), pass the alive
check, and re-arm the delayed work?

drivers/pci/switch/switchtec.c:switchtec_dev_write() {
	...
	rc = lock_mutex_and_test_alive(stdev);
	if (rc)
		return rc;
	...
	schedule_delayed_work(&stdev->mrpc_timeout, ...);
}

If the timeout fires later, could this result in a use-after-free when
stdev has already been freed by devres?

[ ... ]

> @@ -1529,7 +1539,11 @@ static int switchtec_init_isr(struct switchtec_dev *stdev)
>  				switchtec_dma_mrpc_isr, 0,
>  				KBUILD_MODNAME, stdev);
>  
> -	return rc;
> +	if (rc)
> +		return rc;

[Severity: High]
This isn't a bug introduced by this patch, but if switchtec_init_isr() fails
here, does the probe error path leak resources or cause a use-after-free?

If we return rc here, the caller switchtec_pci_probe() jumps to err_exit_pci:

drivers/pci/switch/switchtec.c:switchtec_pci_probe() {
	...
	rc = switchtec_init_isr(stdev);
	if (rc) {
		dev_err(&stdev->dev, "failed to init isr.\n");
		goto err_exit_pci;
	}
	...
err_devadd:
	stdev_kill(stdev);
err_exit_pci:
	switchtec_exit_pci(stdev);
err_put:
	ida_free(&switchtec_minor_ida, MINOR(stdev->dev.devt));
	put_device(&stdev->dev);
}

Since err_exit_pci bypasses stdev_kill(), active devm-managed IRQs and
uncancelled workqueues (like mrpc_work) are not cleaned up before
put_device() frees stdev.

Could an interrupt fire during this window and execute switchtec_event_isr(),
leading to a use-after-free of stdev?

> +	stdev->dma_mrpc_irq = dma_mrpc_irq;
> +
> +	return 0;
>  }

Additionally, while reviewing the code, I noticed another pre-existing issue
in mrpc_complete_cmd():

[Severity: High]
This is a pre-existing issue, but is there a missing dma_rmb() between
reading the DMA status and the DMA data?

drivers/pci/switch/switchtec.c:mrpc_complete_cmd() {
	if (stdev->dma_mrpc)
		stuser->status = stdev->dma_mrpc->status;
	else
		stuser->status = ioread32(&stdev->mmio_mrpc->status);

	if (stuser->status == SWITCHTEC_MRPC_STATUS_INPROGRESS)
		return;
	...
	if (stdev->dma_mrpc)
		memcpy(stuser->data, &stdev->dma_mrpc->data,
			      stuser->read_len);
}

Since the DMA buffer is allocated with dma_alloc_coherent(), memory accesses
are coherent but not strictly ordered on weakly-ordered architectures like
ARM64.

Can the CPU speculatively read the payload data before the status
read completes, resulting in stale data being processed?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/1f52d931ec7a7f5b36837cabf07b36e0463bf182.1785982054.git.xiaopei01@kylinos.cn?part=1

  reply	other threads:[~2026-08-06  2:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-06  2:12 [PATCH v2] PCI: switchtec: Fix use-after-free in switchtec_pci_remove due to race condition Pei Xiao
2026-08-06  2:37 ` sashiko-bot [this message]
2026-08-06 15:32 ` Logan Gunthorpe

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=20260806023711.52FA71F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=xiaopei01@kylinos.cn \
    /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.