Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: Fix refcount issue in pci_create_root_bus() error recovery path

After calling device_register(&bridge->dev), the bridge is reference-
counted, and it is illegal to call kfree() on it except in the release
function.

[bhelgaas: changelog, use put_device() after device_register() failure]
Signed-off-by: Jiang Liu <jiang.liu@huawei.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Cc: stable@vger.kernel.org

authored by

Jiang Liu and committed by
Bjorn Helgaas
343df771 a649dbfe

+8 -6
+8 -6
drivers/pci/probe.c
··· 1711 1711 bridge->dev.release = pci_release_bus_bridge_dev; 1712 1712 dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); 1713 1713 error = pcibios_root_bridge_prepare(bridge); 1714 - if (error) 1715 - goto bridge_dev_reg_err; 1714 + if (error) { 1715 + kfree(bridge); 1716 + goto err_out; 1717 + } 1716 1718 1717 1719 error = device_register(&bridge->dev); 1718 - if (error) 1719 - goto bridge_dev_reg_err; 1720 + if (error) { 1721 + put_device(&bridge->dev); 1722 + goto err_out; 1723 + } 1720 1724 b->bridge = get_device(&bridge->dev); 1721 1725 device_enable_async_suspend(b->bridge); 1722 1726 pci_set_bus_of_node(b); ··· 1776 1772 class_dev_reg_err: 1777 1773 put_device(&bridge->dev); 1778 1774 device_unregister(&bridge->dev); 1779 - bridge_dev_reg_err: 1780 - kfree(bridge); 1781 1775 err_out: 1782 1776 kfree(b); 1783 1777 return NULL;