When device_register() fails for the root bus, the unregister path in pci_register_host_bridge() drops a bridge reference with put_device() and then releases the bus with put_device(&bus->dev). The bus release callback, release_pcibus_dev(), also drops bus->bridge, so the bridge loses two references for the one taken when the bus was set up. This frees the host bridge before pci_register_host_bridge() returns. The caller then drops its own reference on freed memory, either in pci_create_root_bus() or in the devres action of devm_pci_alloc_host_bridge(). KASAN reports the use after free in pci_host_probe() when the bus device registration fails: BUG: KASAN: slab-use-after-free in pci_host_probe+0x17c/0x180 Read of size 8 at addr ffff00000699d840 by task insmod/61 Freed by task 61: kfree+0x274/0x4ec pci_release_host_bridge_dev+0x88/0xa4 device_release+0x9c/0x1ec kobject_put+0x138/0x24c put_device+0x10/0x1c release_pcibus_dev+0x30/0x60 device_release+0x9c/0x1ec kobject_put+0x138/0x24c put_device+0x10/0x1c pci_register_host_bridge+0x63c/0x1244 pci_scan_root_bus_bridge+0x110/0x24c pci_host_probe+0x34/0x180 refcount_t: underflow; use-after-free. Tested on arm64 under QEMU/KVM with KASAN, using a test module that occupies the pci_bus sysfs name so that device_register() of the root bus fails with -EEXIST. With the fix, pci_host_probe() returns the error and the devres teardown completes without KASAN or refcount warnings. Fixes: 804443c1f278 ("PCI: Fix reference leak in pci_register_host_bridge()") Cc: stable@vger.kernel.org Assisted-by: LLM Signed-off-by: Nirmoy Das --- drivers/pci/probe.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 9a178e0e5f7f467..86dbfd4873963e8 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -1149,7 +1149,6 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge) return 0; unregister: - put_device(&bridge->dev); device_del(&bridge->dev); free: #ifdef CONFIG_PCI_DOMAINS_GENERIC -- 2.43.0