Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b7fbbdd authored by Nishka Dasgupta's avatar Nishka Dasgupta Committed by Greg Kroah-Hartman
Browse files

PCI: tegra: Fix OF node reference leak



[ Upstream commit 9e38e690ace3e7a22a81fc02652fc101efb340cf ]

Each iteration of for_each_child_of_node() executes of_node_put() on the
previous node, but in some return paths in the middle of the loop
of_node_put() is missing thus causing a reference leak.

Hence stash these mid-loop return values in a variable 'err' and add a
new label err_node_put which executes of_node_put() on the previous node
and returns 'err' on failure.

Change mid-loop return statements to point to jump to this label to
fix the reference leak.

Issue found with Coccinelle.

Signed-off-by: default avatarNishka Dasgupta <nishkadg.linux@gmail.com>
[lorenzo.pieralisi@arm.com: rewrote commit log]
Signed-off-by: default avatarLorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent c74a801d
Loading
Loading
Loading
Loading
+15 −7
Original line number Diff line number Diff line
@@ -1975,14 +1975,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
		err = of_pci_get_devfn(port);
		if (err < 0) {
			dev_err(dev, "failed to parse address: %d\n", err);
			return err;
			goto err_node_put;
		}

		index = PCI_SLOT(err);

		if (index < 1 || index > soc->num_ports) {
			dev_err(dev, "invalid port number: %d\n", index);
			return -EINVAL;
			err = -EINVAL;
			goto err_node_put;
		}

		index--;
@@ -1991,12 +1992,13 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
		if (err < 0) {
			dev_err(dev, "failed to parse # of lanes: %d\n",
				err);
			return err;
			goto err_node_put;
		}

		if (value > 16) {
			dev_err(dev, "invalid # of lanes: %u\n", value);
			return -EINVAL;
			err = -EINVAL;
			goto err_node_put;
		}

		lanes |= value << (index << 3);
@@ -2010,13 +2012,15 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
		lane += value;

		rp = devm_kzalloc(dev, sizeof(*rp), GFP_KERNEL);
		if (!rp)
			return -ENOMEM;
		if (!rp) {
			err = -ENOMEM;
			goto err_node_put;
		}

		err = of_address_to_resource(port, 0, &rp->regs);
		if (err < 0) {
			dev_err(dev, "failed to parse address: %d\n", err);
			return err;
			goto err_node_put;
		}

		INIT_LIST_HEAD(&rp->list);
@@ -2043,6 +2047,10 @@ static int tegra_pcie_parse_dt(struct tegra_pcie *pcie)
		return err;

	return 0;

err_node_put:
	of_node_put(port);
	return err;
}

/*