@@ -822,6 +822,7 @@ void of_pci_remove_host_bridge_node(struct pci_host_bridge *bridge)
if (!np || !of_node_check_flag(np, OF_DYNAMIC))
return;
+ fw_devlink_set_device(&np->fwnode, NULL);
device_remove_of_node(&bridge->bus->dev);
device_remove_of_node(&bridge->dev);
of_changeset_revert(np->data);
@@ -887,7 +888,7 @@ void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge)
ret = of_changeset_apply(cset);
if (ret)
- goto out_free_node;
+ goto out_clear_devlink_dev;
np->data = cset;
@@ -909,6 +910,8 @@ void of_pci_make_host_bridge_node(struct pci_host_bridge *bridge)
out_revert_cset:
np->data = NULL;
of_changeset_revert(cset);
+out_clear_devlink_dev:
+ fw_devlink_set_device(&np->fwnode, NULL);
out_free_node:
of_node_put(np);
out_destroy_cset:
During the of_pci_make_host_bridge_node() call, an OF node is created dynamically and its fwnode device (fwnode->dev) is set to the PCI root bridge device using the fw_devlink_set_device(&np->fwnode, &bridge->dev) call. On removal, of_pci_remove_host_bridge_node() is called and calls device_remove_of_node() which in turn set to NULL the related dev->fwnode. Later in the removal sequence, device_del() is called and runs its cleanup logic: if (dev->fwnode && dev->fwnode->dev == dev) fw_devlink_set_device(dev->fwnode, NULL); Because dev->fwnode has been cleared earlier, fw_devlink_set_device() is not called and leaves fwnode->dev unchanged. This fwnode device (fwnode->dev) becomes an dangling pointer. If any reference to the OF node is held after this removal, the pointer is still accessible using the OF node (np->fwnode.dev) but points to a freed area. The exact same issue is present in the of_pci_make_host_bridge_node() error path leading to the exact same dangling fwnode->dev. Avoid this dangling fwnode->dev pointer by clearing it in of_pci_remove_host_bridge_node() and in of_pci_make_host_bridge_node() error path. Fixes: 1f340724419e ("PCI: of: Create device tree PCI host bridge node") Cc: stable@vger.kernel.org Signed-off-by: Herve Codina <herve.codina@bootlin.com> Reviewed-by: Richard Cheng <icheng@nvidia.com> Acked-by: Manivannan Sadhasivam <manivannan.sadhasivam@oss.qualcomm.com> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com> --- drivers/pci/of.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)