This patch series is to fix OF device node refcount leakage for - of_irq_parse_and_map_pci() - of_pci_prop_intr_map()
Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com --- Zijun Hu (2): PCI: of: Fix OF device node refcount leakage in API of_irq_parse_and_map_pci() PCI: of: Fix OF device node refcount leakages in of_pci_prop_intr_map()
drivers/pci/of.c | 2 ++ drivers/pci/of_property.c | 20 +++++++++++--------- 2 files changed, 13 insertions(+), 9 deletions(-) --- base-commit: 7d06015d936c861160803e020f68f413b5c3cd9d change-id: 20250407-fix_of_pci-20b45dcc26b5
Best regards,
From: Zijun Hu quic_zijuhu@quicinc.com
Successful of_irq_parse_raw() invocation will increase refcount of OF device node @out_irq[].np, but of_pci_prop_intr_map() does not decrease the refcount before return, so cause @out_irq[].np refcount leakages.
Fix by putting @out_irq[].np refcount before return.
Fixes: 407d1a51921e ("PCI: Create device tree node for bridge") Cc: Rob Herring (Arm) robh@kernel.org Cc: stable@vger.kernel.org Signed-off-by: Zijun Hu quic_zijuhu@quicinc.com --- drivers/pci/of_property.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/drivers/pci/of_property.c b/drivers/pci/of_property.c index 506fcd5071139e0c11130f4c36f5082ed9789efb..4250a78fafbec4c29af124d7ba5ece7b0b785fb3 100644 --- a/drivers/pci/of_property.c +++ b/drivers/pci/of_property.c @@ -258,12 +258,16 @@ static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs, * Parsing interrupt failed for all pins. In this case, it does not * need to generate interrupt-map property. */ - if (!map_sz) - return 0; + if (!map_sz) { + ret = 0; + goto out_put_nodes; + }
int_map = kcalloc(map_sz, sizeof(u32), GFP_KERNEL); - if (!int_map) - return -ENOMEM; + if (!int_map) { + ret = -ENOMEM; + goto out_put_nodes; + } mapp = int_map;
list_for_each_entry(child, &pdev->subordinate->devices, bus_list) { @@ -305,14 +309,12 @@ static int of_pci_prop_intr_map(struct pci_dev *pdev, struct of_changeset *ocs, ret = of_changeset_add_prop_u32_array(ocs, np, "interrupt-map-mask", int_map_mask, ARRAY_SIZE(int_map_mask)); - if (ret) - goto failed; - - kfree(int_map); - return 0;
failed: kfree(int_map); +out_put_nodes: + for (i = 0; i < OF_PCI_MAX_INT_PIN; i++) + of_node_put(out_irq[i].np); return ret; }
linux-stable-mirror@lists.linaro.org