[PATCH v4] net: ethernet: renesas: rswitch: fix device_node refcount leak in rswitch_get_port_node()

"Manush Prajwal" <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-renesas-soc
Message-ID <[email protected]>
On an of_property_read_u32() failure, rswitch_get_port_node() set port
to NULL and jumped to the out label before releasing the reference the
for_each_available_child_of_node() iterator was holding on it. Once
port was overwritten with NULL, that reference could never be
released since out: only put "ports", the parent node.

Rework the function around for_each_available_child_of_node_scoped()
instead of adding a manual of_node_put(), so the iterator's reference
is dropped automatically on every exit path. Since port is the
function's return value, take an explicit reference with of_node_get()
on the match before breaking out of the loop.

Signed-off-by: Manush Prajwal <[email protected]>
---
v4: Keep the err/if (err < 0) structure as-is instead of collapsing
    it into a single-line check, to keep the diff minimal, per Andrew
    Lunn's review.
v3: Reorder local variable declarations into reverse Christmas tree
    order, per Andrew Lunn's review.
v2: Rework using for_each_available_child_of_node_scoped() instead of
    a manual of_node_put(), per Andrew Lunn's review.

 drivers/net/ethernet/renesas/rswitch_main.c | 20 +++++++++-----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/renesas/rswitch_main.c b/drivers/net/ethernet/renesas/rswitch_main.c
index 6fe9648163..1a2b3c4d5e 100644
--- a/drivers/net/ethernet/renesas/rswitch_main.c
+++ b/drivers/net/ethernet/renesas/rswitch_main.c
@@ -1303,8 +1303,9 @@
 /* Call of_node_put(port) after done */
 static struct device_node *rswitch_get_port_node(struct rswitch_device *rdev)
 {
-	struct device_node *ports, *port;
-	int err = 0;
+	struct device_node *port = NULL;
+	struct device_node *ports;
+	int err = 0;
 	u32 index;

 	ports = of_get_child_by_name(rdev->ndev->dev.parent->of_node,
@@ -1312,17 +1313,16 @@ static struct device_node *rswitch_get_port_node(struct rswitch_device *rdev)
 	if (!ports)
 		return NULL;

-	for_each_available_child_of_node(ports, port) {
-		err = of_property_read_u32(port, "reg", &index);
-		if (err < 0) {
-			port = NULL;
-			goto out;
-		}
-		if (index == rdev->etha->index)
+	for_each_available_child_of_node_scoped(ports, child) {
+		err = of_property_read_u32(child, "reg", &index);
+		if (err < 0)
 			break;
+		if (index == rdev->etha->index) {
+			port = of_node_get(child);
+			break;
+		}
 	}

-out:
 	of_node_put(ports);

 	return port;
--
2.46.2.windows.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.