Skip to contentSkip to conversation

usb: ulpi: Add missing of_node_get() in ulpi_of_register()

PATCH In review Stephen Boyd 2 participants 3 messages Nov 11, 2017

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 usb: ulpi: Add missing of_node_get() in ulpi_of_register()

In ulpi_of_register() we call of_find_node_by_name() which unconditionally calls of_node_put() on the 'from' argument. We haven't called of_node_get() though, so we've put the node once without getting it first. Add the of_node_get() call so that things are properly balanced.

Fixes ef6a7bcfb01c ("usb: ulpi: Support device discovery via DT")
---
 drivers/usb/common/ulpi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/common/ulpi.c +2 -2
index 4aa5195db8ea..59e05eff76f9 100644
@@ -182,9 +182,9 @@ static int ulpi_of_register(struct ulpi *ulpi)
 
 	/* Find a ulpi bus underneath the parent or the grandparent */
 	parent = ulpi->dev.parent;
-	if (parent->of_node)
+	if (of_node_get(parent->of_node))
 		np = of_find_node_by_name(parent->of_node, "ulpi");
-	else if (parent->parent && parent->parent->of_node)
+	else if (parent->parent && of_node_get(parent->parent->of_node))
 		np = of_find_node_by_name(parent->parent->of_node, "ulpi");
 	if (!np)
 		return 0;
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project
#1 lore raw
Quoted 18 lines · Stephen Boyd

In ulpi_of_register() we call of_find_node_by_name() which unconditionally calls of_node_put() on the 'from' argument. We haven't called of_node_get() though, so we've put the node once without getting it first. Add the of_node_get() call so that things are properly balanced.

Fixes ef6a7bcfb01c ("usb: ulpi: Support device discovery via DT")
---
 drivers/usb/common/ulpi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/common/ulpi.c +0 -0
index 4aa5195db8ea..59e05eff76f9 100644

drivers/usb/common/ulpi.c static int ulpi_of_register(struct ulpi *ulpi) · line 188

Quoted 9 lines
drivers/usb/common/ulpi.c +2 -2
@@ -182,9 +182,9 @@ static int ulpi_of_register(struct ulpi *ulpi)
 
 	/* Find a ulpi bus underneath the parent or the grandparent */
 	parent = ulpi->dev.parent;
-	if (parent->of_node)
+	if (of_node_get(parent->of_node))
 		np = of_find_node_by_name(parent->of_node, "ulpi");
-	else if (parent->parent && parent->parent->of_node)
+	else if (parent->parent && of_node_get(parent->parent->of_node))
 		np = of_find_node_by_name(parent->parent->of_node, "ulpi");

I'm afraid this isn't the right fix; the code shouldn't have been using of_find_node_by_name() in the first place as that function searches the whole device tree depth-first starting at the parent (or grand parent), which could end up matching an unrelated node.

of_get_child_by_name() is the helper to use for such lookups instead.

Turns out we have a few other driver with similar bugs. I've started fixing a few of them that'll be sending out per subsystem.

I'll post a fix for this one as follow up to this mail meanwhile.

Thanks,
Johan

#2 lore raw

PATCH 1/1 USB: ulpi: fix bus-node lookup

In reply to Stephen Boyd

Fix bus-node lookup during registration, which ended up searching the whole device tree depth-first starting at the parent (or grand parent) rather than just matching on its children.

To make things worse, the parent (or grand-parent) node could end being prematurely freed as well.

Fixes ef6a7bcfb01c ("usb: ulpi: Support device discovery via DT")
Cc stable <[email protected]> # 4.10
---
 drivers/usb/common/ulpi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/common/ulpi.c +2 -2
index 8b351444cc40..9a2ab6751a23 100644
@@ -180,9 +180,9 @@ static int ulpi_of_register(struct ulpi *ulpi)
 	/* Find a ulpi bus underneath the parent or the grandparent */
 	parent = ulpi->dev.parent;
 	if (parent->of_node)
-		np = of_find_node_by_name(parent->of_node, "ulpi");
+		np = of_get_child_by_name(parent->of_node, "ulpi");
 	else if (parent->parent && parent->parent->of_node)
-		np = of_find_node_by_name(parent->parent->of_node, "ulpi");
+		np = of_get_child_by_name(parent->parent->of_node, "ulpi");
 	if (!np)
 		return 0;
 
Signature · 1 line
2.15.0