diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2017-12-07 05:15:19 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2017-12-12 12:01:47 -0500 |
commit | 0c31f1d7be1b5c4858b1d714dcefa25f41428cab (patch) | |
tree | e39aee603c3c12ad4600cec69431e0e4ab5f7746 | |
parent | a19e2696135efb471981c1ae1ec3cb2b70c41a2e (diff) |
PCI: rcar: Fix use-after-free in probe error path
If CONFIG_DEBUG_SLAB=y, and no PCIe card is inserted, the kernel crashes
during probe on r8a7791/koelsch:
rcar-pcie fe000000.pcie: PCIe link down
Unable to handle kernel paging request at virtual address 6b6b6b6b
(seeing this message requires earlycon and keep_bootcon).
Indeed, pci_free_host_bridge() frees the PCI host bridge, including the
embedded rcar_pcie object, so pci_free_resource_list() must not be called
afterwards.
To fix this, move the call to pci_free_resource_list() up, and update the
label name accordingly.
Fixes: ddd535f1ea3eb27e ("PCI: rcar: Fix memory leak when no PCIe card is inserted")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Simon Horman <horms+renesas@verge.net.au>
Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
-rw-r--r-- | drivers/pci/host/pcie-rcar.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c index 12796eccb2be..52ab3cb0a0bf 100644 --- a/drivers/pci/host/pcie-rcar.c +++ b/drivers/pci/host/pcie-rcar.c | |||
@@ -1128,12 +1128,12 @@ static int rcar_pcie_probe(struct platform_device *pdev) | |||
1128 | err = rcar_pcie_get_resources(pcie); | 1128 | err = rcar_pcie_get_resources(pcie); |
1129 | if (err < 0) { | 1129 | if (err < 0) { |
1130 | dev_err(dev, "failed to request resources: %d\n", err); | 1130 | dev_err(dev, "failed to request resources: %d\n", err); |
1131 | goto err_free_bridge; | 1131 | goto err_free_resource_list; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); | 1134 | err = rcar_pcie_parse_map_dma_ranges(pcie, dev->of_node); |
1135 | if (err) | 1135 | if (err) |
1136 | goto err_free_bridge; | 1136 | goto err_free_resource_list; |
1137 | 1137 | ||
1138 | pm_runtime_enable(dev); | 1138 | pm_runtime_enable(dev); |
1139 | err = pm_runtime_get_sync(dev); | 1139 | err = pm_runtime_get_sync(dev); |
@@ -1176,9 +1176,9 @@ err_pm_put: | |||
1176 | err_pm_disable: | 1176 | err_pm_disable: |
1177 | pm_runtime_disable(dev); | 1177 | pm_runtime_disable(dev); |
1178 | 1178 | ||
1179 | err_free_bridge: | 1179 | err_free_resource_list: |
1180 | pci_free_host_bridge(bridge); | ||
1181 | pci_free_resource_list(&pcie->resources); | 1180 | pci_free_resource_list(&pcie->resources); |
1181 | pci_free_host_bridge(bridge); | ||
1182 | 1182 | ||
1183 | return err; | 1183 | return err; |
1184 | } | 1184 | } |