* [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free
2026-11-08 10:56 [PATCH 0/3] PCI: Fix ECAM config window use-after-free in five drivers Hongyan Xu
@ 2026-11-08 10:56 ` Hongyan Xu
2026-11-08 11:14 ` sashiko-bot
2026-11-08 14:21 ` Marc Zyngier
2026-11-08 10:56 ` [PATCH 2/3] PCI: microchip: " Hongyan Xu
2026-11-08 10:56 ` [PATCH 3/3] PCI: thunder-pem, hisi, thunder-ecam: " Hongyan Xu
2 siblings, 2 replies; 8+ messages in thread
From: Hongyan Xu @ 2026-11-08 10:56 UTC (permalink / raw)
To: Bjorn Helgaas, linux-pci
Cc: Marc Zyngier, Daire McNamara, Conor Dooley, Robert Richter,
Zhou Wang, Lorenzo Pieralisi, Krzysztof Wilczynski,
Manivannan Sadhasivam, Rob Herring, linux-arm-kernel, linux-riscv,
linux-kernel, stable, Hongyan Xu
pcie-apple.c has no ->remove for pci_host_common_init(), so unbinding only
runs devres_release_all(): gen_pci_unmap_cfg() -> pci_ecam_free() frees the
ECAM config window while the bus tree stays registered - only
pci_remove_bus() unlinks a bus, and only pci_host_common_remove() reaches
it for a root bus. The next config access is a use-after-free in
pci_ecam_map_bus(), which reads cfg->ops->bus_shift.
Trigger: CONFIG_PCIE_APPLE=m; as root, one command: # rmmod apple_pcie
Fix: add .remove = pci_host_common_remove, as pci-host-generic.c does since
commit 01fcb7f777a9 ("PCI: Add support for unbinding the generic PCI host
controller"), so pci_remove_root_bus() unlinks the bus before devres frees
cfg. Scope: cfg lifetime only; its IRQ handlers stay unreleased, so the
module is still unsafe to unload.
Fixes: 1e33888fbe44 ("PCI: apple: Add initial hardware bring-up")
Cc: stable@vger.kernel.org
Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
---
drivers/pci/controller/pcie-apple.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
index 2d92fc79f6dd..805171551e01 100644
--- a/drivers/pci/controller/pcie-apple.c
+++ b/drivers/pci/controller/pcie-apple.c
@@ -884,6 +884,7 @@ MODULE_DEVICE_TABLE(of, apple_pcie_of_match);
static struct platform_driver apple_pcie_driver = {
.probe = apple_pcie_probe,
+ .remove = pci_host_common_remove,
.driver = {
.name = "pcie-apple",
.of_match_table = apple_pcie_of_match,
--
2.50.1.windows.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free
2026-11-08 10:56 ` [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free Hongyan Xu
@ 2026-11-08 11:14 ` sashiko-bot
2026-11-08 14:21 ` Marc Zyngier
1 sibling, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-11-08 11:14 UTC (permalink / raw)
To: Hongyan Xu, linux-pci
Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [High] PCI: apple: incomplete IRQ and domain teardown in
pci_host_common_remove()
It also noticed 1 related pre-existing issue this patch does not
introduce:
- [Critical] PCI: apple: MSI irq_domain leak and use-after-free in
apple_pcie_probe() [1]
--
commit 6595d3b06ad4c1310264ede81b930782370102fe
Author: Hongyan Xu <getshell@seu.edu.cn>
PCI: apple: Fix ECAM config window use-after-free
This commit wires pci_host_common_remove() as the platform driver remove
callback so the PCI root bus is removed before devres frees the ECAM
configuration window.
> diff --git a/drivers/pci/controller/pcie-apple.c b/drivers/pci/controller/pcie-apple.c
> index c2cffc0659f44..a1e8a3a0ef1dc 100644
> --- a/drivers/pci/controller/pcie-apple.c
> +++ b/drivers/pci/controller/pcie-apple.c
> @@ -886,6 +886,7 @@ MODULE_DEVICE_TABLE(of, apple_pcie_of_match);
>
> static struct platform_driver apple_pcie_driver = {
> .probe = apple_pcie_probe,
[Severity: Critical]
This problem wasn't introduced by this patch, but does apple_pcie_probe()
leak the MSI parent irq_domain [1] if pci_host_common_init() fails?
apple_msi_init() creates an unmanaged IRQ domain via
msi_create_parent_irq_domain() with host_data set to the devm-allocated
struct apple_pcie before calling pci_host_common_init():
drivers/pci/controller/pcie-apple.c:apple_pcie_probe() {
...
ret = apple_msi_init(pcie);
if (ret)
return ret;
return pci_host_common_init(pdev, bridge, &apple_pcie_cfg_ecam_ops);
}
If pci_host_common_init() fails or defers (for example when
apple_pcie_setup_port() defers on GPIO or reset acquisition), devres frees
bridge and pcie->bitmap while the MSI irq_domain stays on irq_domain_list
with a dangling host_data pointer, causing a use-after-free on subsequent
domain lookups or probe retries.
> + .remove = pci_host_common_remove,
[Severity: High]
Does wiring pci_host_common_remove() alone leave the unmanaged IRQ
domains, port interrupts, and chained handlers active after rmmod?
During probe, apple_msi_init() registers an unmanaged MSI parent domain
via msi_create_parent_irq_domain(), and for each port
apple_pcie_setup_port() takes an OF node reference via of_node_get(),
creates a linear IRQ domain via irq_domain_create_linear(), sets
apple_port_irq_handler() via irq_set_chained_handler_and_data(), and
requests link up/down virqs via request_irq().
pci_host_common_remove() only removes the PCI root bus. When rmmod
runs, devres frees struct apple_pcie and struct apple_pcie_port and unmaps
MMIO, and free_module() unmaps the module text and rodata while those IRQ
domains and handlers remain registered. Reading /proc/interrupts or
receiving a port interrupt then faults on unmapped module memory and
freed port state. Should this driver either use builtin_platform_driver()
(matching .suppress_bind_attrs = true) or provide a remove callback that
masks port interrupts and tears down the requested IRQs, chained handlers,
IRQ domains, and OF node references?
[1] https://sashiko.dev/#/bug/linux-93248aea-1b69-486f-9e9f-a90f7de2b348
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261108105640.875-1-getshell@seu.edu.cn?part=1
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free
2026-11-08 10:56 ` [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free Hongyan Xu
2026-11-08 11:14 ` sashiko-bot
@ 2026-11-08 14:21 ` Marc Zyngier
1 sibling, 0 replies; 8+ messages in thread
From: Marc Zyngier @ 2026-11-08 14:21 UTC (permalink / raw)
To: Hongyan Xu
Cc: Bjorn Helgaas, linux-pci, Daire McNamara, Conor Dooley,
Robert Richter, Zhou Wang, Lorenzo Pieralisi,
Krzysztof Wilczynski, Manivannan Sadhasivam, Rob Herring,
linux-arm-kernel, linux-riscv, linux-kernel, stable
On Sun, 08 Nov 2026 10:56:37 +0000,
Hongyan Xu <getshell@seu.edu.cn> wrote:
>
> pcie-apple.c has no ->remove for pci_host_common_init(), so unbinding only
> runs devres_release_all(): gen_pci_unmap_cfg() -> pci_ecam_free() frees the
> ECAM config window while the bus tree stays registered - only
> pci_remove_bus() unlinks a bus, and only pci_host_common_remove() reaches
> it for a root bus. The next config access is a use-after-free in
> pci_ecam_map_bus(), which reads cfg->ops->bus_shift.
> Trigger: CONFIG_PCIE_APPLE=m; as root, one command: # rmmod apple_pcie
>
> Fix: add .remove = pci_host_common_remove, as pci-host-generic.c does since
> commit 01fcb7f777a9 ("PCI: Add support for unbinding the generic PCI host
> controller"), so pci_remove_root_bus() unlinks the bus before devres frees
> cfg. Scope: cfg lifetime only; its IRQ handlers stay unreleased, so the
> module is still unsafe to unload.
Then this patch is pointless. Either you prevent the module from being
unloaded, or you fully handle the removal. Any intermediate state is
just churn.
The former is easy enough to do, and gives you the basis to deal with
the latter.
Thanks,
M.
--
Jazz isn't dead. It just smells funny.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/3] PCI: microchip: Fix ECAM config window use-after-free
2026-11-08 10:56 [PATCH 0/3] PCI: Fix ECAM config window use-after-free in five drivers Hongyan Xu
2026-11-08 10:56 ` [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free Hongyan Xu
@ 2026-11-08 10:56 ` Hongyan Xu
2026-11-08 11:06 ` sashiko-bot
2026-11-08 10:56 ` [PATCH 3/3] PCI: thunder-pem, hisi, thunder-ecam: " Hongyan Xu
2 siblings, 1 reply; 8+ messages in thread
From: Hongyan Xu @ 2026-11-08 10:56 UTC (permalink / raw)
To: Bjorn Helgaas, linux-pci
Cc: Marc Zyngier, Daire McNamara, Conor Dooley, Robert Richter,
Zhou Wang, Lorenzo Pieralisi, Krzysztof Wilczynski,
Manivannan Sadhasivam, Rob Herring, linux-arm-kernel, linux-riscv,
linux-kernel, stable, Hongyan Xu
mc_host_probe() calls pci_host_common_probe() but has no ->remove, so an
unbind only runs devres_release_all(): gen_pci_unmap_cfg() ->
pci_ecam_free() frees the ECAM config window while the bus tree stays
registered - only pci_remove_bus() unlinks a bus, and only
pci_host_common_remove() reaches it for a root bus. The next config access
is a use-after-free in pci_ecam_map_bus(), which reads cfg->ops->bus_shift.
Trigger: overlay rmdir in configfs, not rmmod (builtin_platform_driver()).
Fix: add .remove = pci_host_common_remove, as pci-host-generic.c does since
commit 01fcb7f777a9 ("PCI: Add support for unbinding the generic PCI host
controller"), so pci_remove_root_bus() unlinks the bus before devres frees
cfg. Scope: the PLDA IRQ domains it creates are not devres managed and
stay unreleased - a separate, pre-existing issue.
Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver")
Cc: stable@vger.kernel.org
Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
---
drivers/pci/controller/plda/pcie-microchip-host.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/pci/controller/plda/pcie-microchip-host.c b/drivers/pci/controller/plda/pcie-microchip-host.c
index 24bbf93b8051..f7b75013d9fc 100644
--- a/drivers/pci/controller/plda/pcie-microchip-host.c
+++ b/drivers/pci/controller/plda/pcie-microchip-host.c
@@ -821,6 +821,7 @@ MODULE_DEVICE_TABLE(of, mc_pcie_of_match);
static struct platform_driver mc_pcie_driver = {
.probe = mc_host_probe,
+ .remove = pci_host_common_remove,
.driver = {
.name = "microchip-pcie",
.of_match_table = mc_pcie_of_match,
--
2.50.1.windows.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 2/3] PCI: microchip: Fix ECAM config window use-after-free
2026-11-08 10:56 ` [PATCH 2/3] PCI: microchip: " Hongyan Xu
@ 2026-11-08 11:06 ` sashiko-bot
0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-11-08 11:06 UTC (permalink / raw)
To: Hongyan Xu, linux-pci
> mc_host_probe() calls pci_host_common_probe() but has no ->remove, so an
> unbind only runs devres_release_all(): gen_pci_unmap_cfg() ->
> pci_ecam_free() frees the ECAM config window while the bus tree stays
> registered - only pci_remove_bus() unlinks a bus, and only
> pci_host_common_remove() reaches it for a root bus. The next config access
> is a use-after-free in pci_ecam_map_bus(), which reads cfg->ops->bus_shift.
> Trigger: overlay rmdir in configfs, not rmmod (builtin_platform_driver()).
>
> Fix: add .remove = pci_host_common_remove, as pci-host-generic.c does since
> commit 01fcb7f777a9 ("PCI: Add support for unbinding the generic PCI host
> controller"), so pci_remove_root_bus() unlinks the bus before devres frees
> cfg. Scope: the PLDA IRQ domains it creates are not devres managed and
> stay unreleased - a separate, pre-existing issue.
>
> Fixes: 6f15a9c9f941 ("PCI: microchip: Add Microchip PolarFire PCIe controller driver")
> Cc: stable@vger.kernel.org
> Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261108105640.875-1-getshell@seu.edu.cn?part=2
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/3] PCI: thunder-pem, hisi, thunder-ecam: Fix ECAM config window use-after-free
2026-11-08 10:56 [PATCH 0/3] PCI: Fix ECAM config window use-after-free in five drivers Hongyan Xu
2026-11-08 10:56 ` [PATCH 1/3] PCI: apple: Fix ECAM config window use-after-free Hongyan Xu
2026-11-08 10:56 ` [PATCH 2/3] PCI: microchip: " Hongyan Xu
@ 2026-11-08 10:56 ` Hongyan Xu
2026-11-08 11:00 ` sashiko-bot
2 siblings, 1 reply; 8+ messages in thread
From: Hongyan Xu @ 2026-11-08 10:56 UTC (permalink / raw)
To: Bjorn Helgaas, linux-pci
Cc: Marc Zyngier, Daire McNamara, Conor Dooley, Robert Richter,
Zhou Wang, Lorenzo Pieralisi, Krzysztof Wilczynski,
Manivannan Sadhasivam, Rob Herring, linux-arm-kernel, linux-riscv,
linux-kernel, stable, Hongyan Xu
thunder-pem, hisi and thunder-ecam set .probe = pci_host_common_probe but
have no ->remove, so unbinding only runs devres_release_all():
gen_pci_unmap_cfg() -> pci_ecam_free() frees the ECAM config window while
the bus tree stays registered - only pci_remove_bus() unlinks a bus, and
only pci_host_common_remove() reaches it for a root bus. The next config
access in pci_ecam_map_bus() reads cfg->ops->bus_shift.
Trigger: DT overlay removal of the node that supplied or enabled it.
Fix: give each driver the same .remove = pci_host_common_remove that
pci-host-generic.c got in commit 01fcb7f777a9 ("PCI: Add support for
unbinding the generic PCI host controller"), so the unlink comes first.
Fixes: f12b76e56ada ("PCI: thunder: Add PCIe host driver for ThunderX processors")
Fixes: a2ec1996098c ("PCI: hisi: Add DT almost-ECAM support for Hip06/Hip07 host controllers")
Fixes: 7b6e7ba8e81a ("PCI: thunder: Add driver for ThunderX-pass{1,2} on-chip devices")
Cc: stable@vger.kernel.org
Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
---
drivers/pci/controller/dwc/pcie-hisi.c | 1 +
drivers/pci/controller/pci-thunder-ecam.c | 1 +
drivers/pci/controller/pci-thunder-pem.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/drivers/pci/controller/dwc/pcie-hisi.c b/drivers/pci/controller/dwc/pcie-hisi.c
index 3c17897e56fc..5ed58e5db797 100644
--- a/drivers/pci/controller/dwc/pcie-hisi.c
+++ b/drivers/pci/controller/dwc/pcie-hisi.c
@@ -169,6 +169,7 @@ static const struct of_device_id hisi_pcie_almost_ecam_of_match[] = {
static struct platform_driver hisi_pcie_almost_ecam_driver = {
.probe = pci_host_common_probe,
+ .remove = pci_host_common_remove,
.driver = {
.name = "hisi-pcie-almost-ecam",
.of_match_table = hisi_pcie_almost_ecam_of_match,
diff --git a/drivers/pci/controller/pci-thunder-ecam.c b/drivers/pci/controller/pci-thunder-ecam.c
index b5b4a958e6a2..4745f5d00b5a 100644
--- a/drivers/pci/controller/pci-thunder-ecam.c
+++ b/drivers/pci/controller/pci-thunder-ecam.c
@@ -358,6 +358,7 @@ static struct platform_driver thunder_ecam_driver = {
.suppress_bind_attrs = true,
},
.probe = pci_host_common_probe,
+ .remove = pci_host_common_remove,
};
builtin_platform_driver(thunder_ecam_driver);
diff --git a/drivers/pci/controller/pci-thunder-pem.c b/drivers/pci/controller/pci-thunder-pem.c
index 5fa037fb61dc..80cabbf263be 100644
--- a/drivers/pci/controller/pci-thunder-pem.c
+++ b/drivers/pci/controller/pci-thunder-pem.c
@@ -474,6 +474,7 @@ static struct platform_driver thunder_pem_driver = {
.suppress_bind_attrs = true,
},
.probe = pci_host_common_probe,
+ .remove = pci_host_common_remove,
};
builtin_platform_driver(thunder_pem_driver);
--
2.50.1.windows.1
^ permalink raw reply related [flat|nested] 8+ messages in thread* Re: [PATCH 3/3] PCI: thunder-pem, hisi, thunder-ecam: Fix ECAM config window use-after-free
2026-11-08 10:56 ` [PATCH 3/3] PCI: thunder-pem, hisi, thunder-ecam: " Hongyan Xu
@ 2026-11-08 11:00 ` sashiko-bot
0 siblings, 0 replies; 8+ messages in thread
From: sashiko-bot @ 2026-11-08 11:00 UTC (permalink / raw)
To: Hongyan Xu, linux-pci
> thunder-pem, hisi and thunder-ecam set .probe = pci_host_common_probe but
> have no ->remove, so unbinding only runs devres_release_all():
> gen_pci_unmap_cfg() -> pci_ecam_free() frees the ECAM config window while
> the bus tree stays registered - only pci_remove_bus() unlinks a bus, and
> only pci_host_common_remove() reaches it for a root bus. The next config
> access in pci_ecam_map_bus() reads cfg->ops->bus_shift.
> Trigger: DT overlay removal of the node that supplied or enabled it.
>
> Fix: give each driver the same .remove = pci_host_common_remove that
> pci-host-generic.c got in commit 01fcb7f777a9 ("PCI: Add support for
> unbinding the generic PCI host controller"), so the unlink comes first.
>
> Fixes: f12b76e56ada ("PCI: thunder: Add PCIe host driver for ThunderX processors")
> Fixes: a2ec1996098c ("PCI: hisi: Add DT almost-ECAM support for Hip06/Hip07 host controllers")
> Fixes: 7b6e7ba8e81a ("PCI: thunder: Add driver for ThunderX-pass{1,2} on-chip devices")
> Cc: stable@vger.kernel.org
> Signed-off-by: Hongyan Xu <getshell@seu.edu.cn>
Sashiko has reviewed this patch and found no issues.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261108105640.875-1-getshell@seu.edu.cn?part=3
^ permalink raw reply [flat|nested] 8+ messages in thread