* [PATCH 1/2] PCI: remove stray put_device() in pci_register_host_bridge()
[not found] <cover.1741336994.git.dan.carpenter@linaro.org>
@ 2025-03-07 8:46 ` Dan Carpenter
2025-03-07 19:50 ` Bjorn Helgaas
2025-03-07 8:46 ` [PATCH 2/2] PCI: Fix double free " Dan Carpenter
1 sibling, 1 reply; 4+ messages in thread
From: Dan Carpenter @ 2025-03-07 8:46 UTC (permalink / raw)
To: Rob Herring
Cc: Bjorn Helgaas, Lorenzo Pieralisi, Arnd Bergmann, linux-pci,
linux-kernel
This put_device() was accidentally left over from when we changed the
code from using device_register() to calling device_add(). Delete it.
Fixes: 9885440b16b8 ("PCI: Fix pci_host_bridge struct device release/free handling")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
drivers/pci/probe.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 9ce83a1d6e31..819d23ce3565 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -999,10 +999,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
/* Temporarily move resources off the list */
list_splice_init(&bridge->windows, &resources);
err = device_add(&bridge->dev);
- if (err) {
- put_device(&bridge->dev);
+ if (err)
goto free;
- }
+
bus->bridge = get_device(&bridge->dev);
device_enable_async_suspend(bus->bridge);
pci_set_bus_of_node(bus);
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] PCI: Fix double free in pci_register_host_bridge()
[not found] <cover.1741336994.git.dan.carpenter@linaro.org>
2025-03-07 8:46 ` [PATCH 1/2] PCI: remove stray put_device() in pci_register_host_bridge() Dan Carpenter
@ 2025-03-07 8:46 ` Dan Carpenter
2025-03-07 19:50 ` Bjorn Helgaas
1 sibling, 1 reply; 4+ messages in thread
From: Dan Carpenter @ 2025-03-07 8:46 UTC (permalink / raw)
To: Ma Ke; +Cc: Bjorn Helgaas, linux-pci, linux-kernel
Calling put_device(&bus->dev) will call release_pcibus_dev() which will
free the bus. It leads to a use after free when we dereference "bus" in
the cleanup code and the kfree(bus) is a double free.
Fixes: b80b4d4972e6 ("PCI: Fix reference leak in pci_register_host_bridge()")
Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
---
drivers/pci/probe.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 819d23ce3565..c13f2c957002 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -957,6 +957,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
resource_size_t offset, next_offset;
LIST_HEAD(resources);
struct resource *res, *next_res;
+ bool bus_registered = false;
char addr[64], *fmt;
const char *name;
int err;
@@ -1020,10 +1021,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
name = dev_name(&bus->dev);
err = device_register(&bus->dev);
- if (err) {
- put_device(&bus->dev);
+ bus_registered = true;
+ if (err)
goto unregister;
- }
pcibios_add_bus(bus);
@@ -1110,12 +1110,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
unregister:
put_device(&bridge->dev);
device_del(&bridge->dev);
-
free:
#ifdef CONFIG_PCI_DOMAINS_GENERIC
pci_bus_release_domain_nr(parent, bus->domain_nr);
#endif
- kfree(bus);
+ if (bus_registered)
+ put_device(&bus->dev);
+ else
+ kfree(bus);
+
return err;
}
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] PCI: remove stray put_device() in pci_register_host_bridge()
2025-03-07 8:46 ` [PATCH 1/2] PCI: remove stray put_device() in pci_register_host_bridge() Dan Carpenter
@ 2025-03-07 19:50 ` Bjorn Helgaas
0 siblings, 0 replies; 4+ messages in thread
From: Bjorn Helgaas @ 2025-03-07 19:50 UTC (permalink / raw)
To: Dan Carpenter
Cc: Rob Herring, Bjorn Helgaas, Lorenzo Pieralisi, Arnd Bergmann,
linux-pci, linux-kernel
On Fri, Mar 07, 2025 at 11:46:34AM +0300, Dan Carpenter wrote:
> This put_device() was accidentally left over from when we changed the
> code from using device_register() to calling device_add(). Delete it.
>
> Fixes: 9885440b16b8 ("PCI: Fix pci_host_bridge struct device release/free handling")
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Applied to pci/enumeration for v6.15, thanks!
> ---
> drivers/pci/probe.c | 5 ++---
> 1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 9ce83a1d6e31..819d23ce3565 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -999,10 +999,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
> /* Temporarily move resources off the list */
> list_splice_init(&bridge->windows, &resources);
> err = device_add(&bridge->dev);
> - if (err) {
> - put_device(&bridge->dev);
> + if (err)
> goto free;
> - }
> +
> bus->bridge = get_device(&bridge->dev);
> device_enable_async_suspend(bus->bridge);
> pci_set_bus_of_node(bus);
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] PCI: Fix double free in pci_register_host_bridge()
2025-03-07 8:46 ` [PATCH 2/2] PCI: Fix double free " Dan Carpenter
@ 2025-03-07 19:50 ` Bjorn Helgaas
0 siblings, 0 replies; 4+ messages in thread
From: Bjorn Helgaas @ 2025-03-07 19:50 UTC (permalink / raw)
To: Dan Carpenter; +Cc: Ma Ke, Bjorn Helgaas, linux-pci, linux-kernel
On Fri, Mar 07, 2025 at 11:46:41AM +0300, Dan Carpenter wrote:
> Calling put_device(&bus->dev) will call release_pcibus_dev() which will
> free the bus. It leads to a use after free when we dereference "bus" in
> the cleanup code and the kfree(bus) is a double free.
>
> Fixes: b80b4d4972e6 ("PCI: Fix reference leak in pci_register_host_bridge()")
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
Squashed into the b80b4d4972e6 commit on pci/enumeration for v6.15,
thanks!
> ---
> drivers/pci/probe.c | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
> index 819d23ce3565..c13f2c957002 100644
> --- a/drivers/pci/probe.c
> +++ b/drivers/pci/probe.c
> @@ -957,6 +957,7 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
> resource_size_t offset, next_offset;
> LIST_HEAD(resources);
> struct resource *res, *next_res;
> + bool bus_registered = false;
> char addr[64], *fmt;
> const char *name;
> int err;
> @@ -1020,10 +1021,9 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
> name = dev_name(&bus->dev);
>
> err = device_register(&bus->dev);
> - if (err) {
> - put_device(&bus->dev);
> + bus_registered = true;
> + if (err)
> goto unregister;
> - }
>
> pcibios_add_bus(bus);
>
> @@ -1110,12 +1110,15 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
> unregister:
> put_device(&bridge->dev);
> device_del(&bridge->dev);
> -
> free:
> #ifdef CONFIG_PCI_DOMAINS_GENERIC
> pci_bus_release_domain_nr(parent, bus->domain_nr);
> #endif
> - kfree(bus);
> + if (bus_registered)
> + put_device(&bus->dev);
> + else
> + kfree(bus);
> +
> return err;
> }
>
> --
> 2.47.2
>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-03-07 19:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <cover.1741336994.git.dan.carpenter@linaro.org>
2025-03-07 8:46 ` [PATCH 1/2] PCI: remove stray put_device() in pci_register_host_bridge() Dan Carpenter
2025-03-07 19:50 ` Bjorn Helgaas
2025-03-07 8:46 ` [PATCH 2/2] PCI: Fix double free " Dan Carpenter
2025-03-07 19:50 ` Bjorn Helgaas
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox