[PATCH 5.11 139/775] net: enetc: fix destroyed phylink dereference during unbind

From: Greg Kroah-Hartman
Date: Mon Mar 01 2021 - 21:49:38 EST


From: Vladimir Oltean <vladimir.oltean@xxxxxxx>

[ Upstream commit 3af409ca278d4a8d50e91f9f7c4c33b175645cf3 ]

The following call path suggests that calling unregister_netdev on an
interface that is up will first bring it down.

enetc_pf_remove
-> unregister_netdev
-> unregister_netdevice_queue
-> unregister_netdevice_many
-> dev_close_many
-> __dev_close_many
-> enetc_close
-> enetc_stop
-> phylink_stop

However, enetc first destroys the phylink instance, then calls
unregister_netdev. This is already dissimilar to the setup (and error
path teardown path) from enetc_pf_probe, but more than that, it is buggy
because it is invalid to call phylink_stop after phylink_destroy.

So let's first unregister the netdev (and let the .ndo_stop events
consume themselves), then destroy the phylink instance, then free the
netdev.

Fixes: 71b77a7a27a3 ("enetc: Migrate to PHYLINK and PCS_LYNX")
Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>
---
drivers/net/ethernet/freescale/enetc/enetc_pf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/freescale/enetc/enetc_pf.c b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
index 3eb5f1375bd4c..515c5b29d7aab 100644
--- a/drivers/net/ethernet/freescale/enetc/enetc_pf.c
+++ b/drivers/net/ethernet/freescale/enetc/enetc_pf.c
@@ -1157,14 +1157,15 @@ static void enetc_pf_remove(struct pci_dev *pdev)
struct enetc_ndev_priv *priv;

priv = netdev_priv(si->ndev);
- enetc_phylink_destroy(priv);
- enetc_mdiobus_destroy(pf);

if (pf->num_vfs)
enetc_sriov_configure(pdev, 0);

unregister_netdev(si->ndev);

+ enetc_phylink_destroy(priv);
+ enetc_mdiobus_destroy(pf);
+
enetc_free_msix(priv);

enetc_free_si_resources(priv);
--
2.27.0