Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
Pre-existing issues:
- [High] The PMU driver stores a pointer to the PCI device (`pdev`) without retaining a reference, exposing the system to a Use-After-Free (UAF) if the PCI device is hot-removed.
- [High] Concurrent modification of the global dwc_pcie_dev_info_head list without locking.
--
--- Patch [1]: [PATCH] perf/dwc_pcie: Fix PCI device reference leak in probe ---
commit 2589eb488a31451ac7fb41c9454a6b4efd3a7453
Author: Ruoyu Wang <[email protected]>
perf/dwc_pcie: Fix PCI device reference leak in probe
This commit addresses a PCI device reference leak when the subsequent RAS
DES capability lookup fails. It moves the pci_dev_put call immediately
after capability discovery to release the reference on both success and
failure paths.
> diff --git a/drivers/perf/dwc_pcie_pmu.c b/drivers/perf/dwc_pcie_pmu.c
> index 6b9ed59de26eb..976e09f0d81b7 100644
> --- a/drivers/perf/dwc_pcie_pmu.c
> +++ b/drivers/perf/dwc_pcie_pmu.c
> @@ -763,10 +763,10 @@ static int dwc_pcie_pmu_probe(struct platform_device *plat_dev)
> }
>
> vsec = dwc_pcie_des_cap(pdev);
> + pci_dev_put(pdev);
[Severity: High]
This is a pre-existing issue, but I have a question about how the PCI device
reference is managed here.
Since pci_dev_put(pdev) is called to drop the reference, is it safe to
subsequently store and dereference this pointer?
In drivers/perf/dwc_pcie_pmu.c:dwc_pcie_pmu_probe(), the pdev pointer is
stored in the PMU structure:
pcie_pmu->pdev = pdev;
If the PCI device is hot-removed during the initialization window before the
bus notifier is registered in dwc_pcie_pmu_init(), the BUS_NOTIFY_DEL_DEVICE
event could be missed. This would mean the PMU platform device is never
unregistered, and the PCI subsystem would free the struct pci_dev.
Could this leave pcie_pmu->pdev pointing to freed memory, leading to a
use-after-free when subsequent PMU operations or CPU hotplug callbacks like
dwc_pcie_pmu_online_cpu() access it?
> if (!vsec)
> return -ENODEV;
>
> - pci_dev_put(pdev);
> name = devm_kasprintf(&plat_dev->dev, GFP_KERNEL, "dwc_rootport_%x", sbdf);
[ ... ]
[Severity: High]
This is a pre-existing issue, but can the global linked list be corrupted
if multiple PCI devices are hot-plugged concurrently?
In drivers/perf/dwc_pcie_pmu.c, the global list dwc_pcie_dev_info_head is
modified without acquiring a lock:
dwc_pcie_register_dev() {
...
list_add(&dev_info->dev_node, &dwc_pcie_dev_info_head);
...
}
dwc_pcie_unregister_dev() {
...
list_del(&dev_info->dev_node);
...
}
These functions are invoked by the driver's PCI bus notifier
(dwc_pcie_pmu_nb) responding to BUS_NOTIFY_ADD_DEVICE and
BUS_NOTIFY_DEL_DEVICE events.
Since the driver core's bus notifier chain uses a read-write semaphore
which allows concurrent hotplug events across different devices to invoke
notifiers simultaneously, couldn't this trigger a data race on list_add
and list_del?
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=1
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.