Skip to content

Commit ed5d293

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: sja1105: fix use-after-free after calling of_find_compatible_node, or worse
It seems that of_find_compatible_node has a weird calling convention in which it calls of_node_put() on the "from" node argument, instead of leaving that up to the caller. This comes from the fact that of_find_compatible_node with a non-NULL "from" argument it only supposed to be used as the iterator function of for_each_compatible_node(). OF iterator functions call of_node_get on the next OF node and of_node_put() on the previous one. When of_find_compatible_node calls of_node_put, it actually never expects the refcount to drop to zero, because the call is done under the atomic devtree_lock context, and when the refcount drops to zero it triggers a kobject and a sysfs file deletion, which assume blocking context. So any driver call to of_find_compatible_node is probably buggy because an unexpected of_node_put() takes place. What should be done is to use the of_get_compatible_child() function. Fixes: 5a8f097 ("net: dsa: sja1105: register the MDIO buses for 100base-T1 and 100base-TX") Link: https://lore.kernel.org/netdev/20210814010139.kzryimmp4rizlznt@skbuf/ Suggested-by: Frank Rowand <[email protected]> Suggested-by: Rob Herring <[email protected]> Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 86b9bbd commit ed5d293

File tree

1 file changed

+2
-4
lines changed

1 file changed

+2
-4
lines changed

drivers/net/dsa/sja1105/sja1105_mdio.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -284,8 +284,7 @@ static int sja1105_mdiobus_base_tx_register(struct sja1105_private *priv,
284284
struct mii_bus *bus;
285285
int rc = 0;
286286

287-
np = of_find_compatible_node(mdio_node, NULL,
288-
"nxp,sja1110-base-tx-mdio");
287+
np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-tx-mdio");
289288
if (!np)
290289
return 0;
291290

@@ -339,8 +338,7 @@ static int sja1105_mdiobus_base_t1_register(struct sja1105_private *priv,
339338
struct mii_bus *bus;
340339
int rc = 0;
341340

342-
np = of_find_compatible_node(mdio_node, NULL,
343-
"nxp,sja1110-base-t1-mdio");
341+
np = of_get_compatible_child(mdio_node, "nxp,sja1110-base-t1-mdio");
344342
if (!np)
345343
return 0;
346344

0 commit comments

Comments
 (0)