Commit 50ac64cf authored by Johan Hovold's avatar Johan Hovold Committed by David S. Miller

net: ethernet: stmmac: dwmac-socfpga: fix use-after-free on probe errors

Make sure to call stmmac_dvr_remove() before returning on late probe
errors so that memory is freed, clocks are disabled, and the netdev is
deregistered before its resources go away.

Fixes: 3c201b5a ("net: stmmac: socfpga: Remove re-registration of
reset controller")
Signed-off-by: default avatarJohan Hovold <johan@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6919756c
...@@ -304,6 +304,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) ...@@ -304,6 +304,8 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
int ret; int ret;
struct socfpga_dwmac *dwmac; struct socfpga_dwmac *dwmac;
struct net_device *ndev;
struct stmmac_priv *stpriv;
ret = stmmac_get_platform_resources(pdev, &stmmac_res); ret = stmmac_get_platform_resources(pdev, &stmmac_res);
if (ret) if (ret)
...@@ -327,19 +329,26 @@ static int socfpga_dwmac_probe(struct platform_device *pdev) ...@@ -327,19 +329,26 @@ static int socfpga_dwmac_probe(struct platform_device *pdev)
plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed; plat_dat->fix_mac_speed = socfpga_dwmac_fix_mac_speed;
ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res); ret = stmmac_dvr_probe(&pdev->dev, plat_dat, &stmmac_res);
if (ret)
return ret;
if (!ret) { ndev = platform_get_drvdata(pdev);
struct net_device *ndev = platform_get_drvdata(pdev); stpriv = netdev_priv(ndev);
struct stmmac_priv *stpriv = netdev_priv(ndev);
/* The socfpga driver needs to control the stmmac reset to /* The socfpga driver needs to control the stmmac reset to set the phy
* set the phy mode. Create a copy of the core reset handel * mode. Create a copy of the core reset handle so it can be used by
* so it can be used by the driver later. * the driver later.
*/ */
dwmac->stmmac_rst = stpriv->stmmac_rst; dwmac->stmmac_rst = stpriv->stmmac_rst;
ret = socfpga_dwmac_set_phy_mode(dwmac); ret = socfpga_dwmac_set_phy_mode(dwmac);
} if (ret)
goto err_dvr_remove;
return 0;
err_dvr_remove:
stmmac_dvr_remove(&pdev->dev);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment