Skip to content
Commit dd336267 authored by Rob Herring's avatar Rob Herring Committed by Greg Kroah-Hartman
Browse files

PCI: Fix pci_host_bridge struct device release/free handling

commit 9885440b upstream.

The PCI code has several paths where the struct pci_host_bridge is freed
directly. This is wrong because it contains a struct device which is
refcounted and should be freed using put_device(). This can result in
use-after-free errors. I think this problem has existed since 2012 with
commit 7b543663 ("PCI: add generic device into pci_host_bridge
struct"). It generally hasn't mattered as most host bridge drivers are
still built-in and can't unbind.

The problem is a struct device should never be freed directly once
device_initialize() is called and a ref is held, but that doesn't happen
until pci_register_host_bridge(). There's then a window between allocating
the host bridge and pci_register_host_bridge() where kfree should be used.
This is fragile and requires callers to do the right thing. To fix this, we
need to split device_register() into device_initialize() and device_add()
calls, so that the host bridge struct is always freed by using a
put_device().

devm_pci_alloc_host_bridge() is using devm_kzalloc() to allocate struct
pci_host_bridge which will be freed directly. Instead, we can use a custom
devres action to call put_device().

Link: https://lore.kernel.org/r/20200513223859.11295-2-robh@kernel.org


Reported-by: default avatarAnders Roxell <anders.roxell@linaro.org>
Tested-by: default avatarAnders Roxell <anders.roxell@linaro.org>
Signed-off-by: default avatarRob Herring <robh@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: default avatarArnd Bergmann <arnd@arndb.de>
[tyhicks: Minor contextual change in pci_init_host_bridge() due to the
 lack of a native_dpc member in the pci_host_bridge struct. It was added
 in v5.7 with commit ac1c8e35

 ("PCI/DPC: Add Error Disconnect
 Recover (EDR) support")]
Signed-off-by: default avatarTyler Hicks <tyhicks@linux.microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e81f3b7e
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment