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

Reply via email to