aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <johan@kernel.org>2018-08-27 04:21:51 -0400
committerRob Herring <robh@kernel.org>2018-10-23 14:28:52 -0400
commitac63043d8cb5503c7e0fe110f947eacf2663804e (patch)
tree282f1824abab7ed062274345df3900f467e9deb6
parentd397dbe606120a1ea1b11b0020c3f7a3852da5ac (diff)
net: stmmac: dwmac-sun8i: fix OF child-node lookup
Use the new of_get_compatible_child() helper to lookup the mdio-internal child node instead of using of_find_compatible_node(), which searches the entire tree from a given start node and thus can return an unrelated (i.e. non-child) node. This also addresses a potential use-after-free (e.g. after probe deferral) as the tree-wide helper drops a reference to its first argument (i.e. the mdio-mux node). Fortunately, this was inadvertently balanced by a failure to drop the mdio-mux reference after lookup. While at it, also fix the related mdio-internal- and phy-node reference leaks. Fixes: 634db83b8265 ("net: stmmac: dwmac-sun8i: Handle integrated/external MDIOs") Tested-by: Corentin Labbe <clabbe.montjoie@gmail.com> Cc: Andrew Lunn <andrew@lunn.ch> Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com> Cc: Alexandre Torgue <alexandre.torgue@st.com> Cc: Jose Abreu <joabreu@synopsys.com> Cc: David S. Miller <davem@davemloft.net> Signed-off-by: Johan Hovold <johan@kernel.org> Signed-off-by: Rob Herring <robh@kernel.org>
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
index f9a61f90cfbc..0f660af01a4b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-sun8i.c
@@ -714,8 +714,9 @@ static int get_ephy_nodes(struct stmmac_priv *priv)
714 return -ENODEV; 714 return -ENODEV;
715 } 715 }
716 716
717 mdio_internal = of_find_compatible_node(mdio_mux, NULL, 717 mdio_internal = of_get_compatible_child(mdio_mux,
718 "allwinner,sun8i-h3-mdio-internal"); 718 "allwinner,sun8i-h3-mdio-internal");
719 of_node_put(mdio_mux);
719 if (!mdio_internal) { 720 if (!mdio_internal) {
720 dev_err(priv->device, "Cannot get internal_mdio node\n"); 721 dev_err(priv->device, "Cannot get internal_mdio node\n");
721 return -ENODEV; 722 return -ENODEV;
@@ -729,13 +730,20 @@ static int get_ephy_nodes(struct stmmac_priv *priv)
729 gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL); 730 gmac->rst_ephy = of_reset_control_get_exclusive(iphynode, NULL);
730 if (IS_ERR(gmac->rst_ephy)) { 731 if (IS_ERR(gmac->rst_ephy)) {
731 ret = PTR_ERR(gmac->rst_ephy); 732 ret = PTR_ERR(gmac->rst_ephy);
732 if (ret == -EPROBE_DEFER) 733 if (ret == -EPROBE_DEFER) {
734 of_node_put(iphynode);
735 of_node_put(mdio_internal);
733 return ret; 736 return ret;
737 }
734 continue; 738 continue;
735 } 739 }
736 dev_info(priv->device, "Found internal PHY node\n"); 740 dev_info(priv->device, "Found internal PHY node\n");
741 of_node_put(iphynode);
742 of_node_put(mdio_internal);
737 return 0; 743 return 0;
738 } 744 }
745
746 of_node_put(mdio_internal);
739 return -ENODEV; 747 return -ENODEV;
740} 748}
741 749