It is possible that scheduled work started by the PHY driver is still outstanding when phy_device_remove is called if the PHY was initially started but never connected, and therefore phy_disconnect is never called. phy_stop does not guarantee that the scheduled work is stopped because it is called under rtnl_lock. This can cause an oops due to use-after-free if the delayed work fires after freeing the PHY device.
Ensure that the state_queue work is cancelled in both phy_device_remove and phy_remove paths. Signed-off-by: Robert Hancock <hanc...@sedsystems.ca> --- drivers/net/phy/phy_device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index 2c879ba..1c90b33 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -877,6 +877,8 @@ int phy_device_register(struct phy_device *phydev) */ void phy_device_remove(struct phy_device *phydev) { + cancel_delayed_work_sync(&phydev->state_queue); + device_del(&phydev->mdio.dev); /* Assert the reset signal */ -- 1.8.3.1