Patch "net: phy: Fix PHY module checks and NULL deref in phy_attach_direct()" has been added to the 4.9-stable tree
Subsystems (3)
This is a note to let you know that I've just added the patch titled
net: phy: Fix PHY module checks and NULL deref in phy_attach_direct()
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.
Quoted 1 line
From foo@baz Thu Jun 15 12:25:36 CEST 2017
From: Florian Fainelli <[email protected]>
Date: Wed, 8 Feb 2017 19:05:26 -0800
Subject: net: phy: Fix PHY module checks and NULL deref in phy_attach_direct()
From: Florian Fainelli <[email protected]>
[ Upstream commit 6d9f66ac7fec2a6ccd649e5909806dfe36f1fc25 ]
The Generic PHY drivers gets assigned after we checked that the current PHY driver is NULL, so we need to check a few things before we can safely dereference d->driver. This would be causing a NULL deference to occur when a system binds to the Generic PHY driver. Update phy_attach_direct() to do the following:
- grab the driver module reference after we have assigned the Generic PHY drivers accordingly, and remember we came from the generic PHY path
- update the error path to clean up the module reference in case the Generic PHY probe function fails
- split the error path involving phy_detacht() to avoid double free/put since phy_detach() does all the clean up
- finally, have phy_detach() drop the module reference count before we call device_release_driver() for the Generic PHY driver case
--- drivers/net/phy/phy_device.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
drivers/net/phy/phy_device.c +21 -8
@@ -860,6 +860,7 @@ int phy_attach_direct(struct net_devicestruct module *ndev_owner = dev->dev.parent->driver->owner;struct mii_bus *bus = phydev->mdio.bus;struct device *d = &phydev->mdio.dev; +bool using_genphy = false;int err;/* For Ethernet device drivers that register their own MDIO bus, we
@@ -872,11 +873,6 @@ int phy_attach_direct(struct net_devicereturn -EIO ; } -if (!try_module_get (d->driver->owner)) { -dev_err (&dev->dev,"failed to get the device driver module\n" ); -return -EIO ; - } -get_device (d);/* Assume that if there is no driver, that it doesn't
@@ -890,12 +886,22 @@ int phy_attach_direct(struct net_device d->driver = &genphy_driver[GENPHY_DRV_1G ].mdiodrv.driver; + using_genphy = true; + } + +if (!try_module_get (d->driver->owner)) { +dev_err (&dev->dev,"failed to get the device driver module\n" ); + err = -EIO ; + goto error_put_device; + } + +if (using_genphy) { err = d->driver->probe (d);if (err >=0 ) err =device_bind_driver (d);if (err) - goto error; + goto error_module_put; }if (phydev->attached_dev) {
@@ -931,8 +937,14 @@ int phy_attach_direct(struct net_devicereturn err; error: -put_device (d); +/* phy_detach() does all of the cleanup below */ +phy_detach (phydev); +return err; + +error_module_put:module_put (d->driver->owner); +error_put_device: +put_device (d);if (ndev_owner != bus->owner)module_put (bus->owner);return err;
@@ -993,6 +1005,8 @@ void phy_detach(struct phy_device *phyde phydev->attached_dev =NULL ;phy_suspend (phydev); +module_put (phydev->mdio.dev.driver->owner); +/* If the device had no specific driver before (i.e. - it * was using the generic driver), we unbind the device * from the generic driver so that there's a chance a
@@ -1013,7 +1027,6 @@ void phy_detach(struct phy_device *phyde bus = phydev->mdio.bus;put_device (&phydev->mdio.dev); -module_put (phydev->mdio.dev.driver->owner);if (ndev_owner != bus->owner)module_put (bus->owner); }
Patches currently in stable-queue which might be from [email protected] are
queue-4.9/net-phy-fix-lack-of-reference-count-on-phy-driver.patch queue-4.9/net-phy-fix-phy-module-checks-and-null-deref-in-phy_attach_direct.patch