]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: of: Destroy changeset when adding PCI device node fails
authorLizhi Hou <lizhi.hou@amd.com>
Fri, 29 Sep 2023 17:10:17 +0000 (10:10 -0700)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 29 Sep 2023 22:33:51 +0000 (17:33 -0500)
Previously of_pci_make_dev_node() leaked a cset if it failed to create a
device node for the PCI device with of_changeset_create_node().

Destroy the cset if of_changeset_create_node() fails.

Fixes: 407d1a51921e ("PCI: Create device tree node for bridge")
Link: https://lore.kernel.org/r/1696007417-42059-1-git-send-email-lizhi.hou@amd.com
Reported-by: Herve Codina <herve.codina@bootlin.com>
Closes: https://lore.kernel.org/all/20230911171319.495bb837@bootlin.com/
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
[bhelgaas: commit log]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Herve Codina <herve.codina@bootlin.com>
drivers/pci/of.c

index 2af64bcb7da3a3e0bc28ab0c99ca54d1d4f7b1f5..51e3dd0ea5abe02c4e9ce07d096f5ded30f26883 100644 (file)
@@ -657,30 +657,33 @@ void of_pci_make_dev_node(struct pci_dev *pdev)
 
        cset = kmalloc(sizeof(*cset), GFP_KERNEL);
        if (!cset)
-               goto failed;
+               goto out_free_name;
        of_changeset_init(cset);
 
        np = of_changeset_create_node(cset, ppnode, name);
        if (!np)
-               goto failed;
-       np->data = cset;
+               goto out_destroy_cset;
 
        ret = of_pci_add_properties(pdev, cset, np);
        if (ret)
-               goto failed;
+               goto out_free_node;
 
        ret = of_changeset_apply(cset);
        if (ret)
-               goto failed;
+               goto out_free_node;
 
+       np->data = cset;
        pdev->dev.of_node = np;
        kfree(name);
 
        return;
 
-failed:
-       if (np)
-               of_node_put(np);
+out_free_node:
+       of_node_put(np);
+out_destroy_cset:
+       of_changeset_destroy(cset);
+       kfree(cset);
+out_free_name:
        kfree(name);
 }
 #endif