• Lukas Wunner's avatar
    usbnet: Run unregister_netdev() before unbind() again · d1408f6b
    Lukas Wunner authored
    Commit 2c9d6c2b ("usbnet: run unbind() before unregister_netdev()")
    sought to fix a use-after-free on disconnect of USB Ethernet adapters.
    
    It turns out that a different fix is necessary to address the issue:
    https://lore.kernel.org/netdev/18b3541e5372bc9b9fc733d422f4e698c089077c.1650177997.git.lukas@wunner.de/
    
    So the commit was not necessary.
    
    The commit made binding and unbinding of USB Ethernet asymmetrical:
    Before, usbnet_probe() first invoked the ->bind() callback and then
    register_netdev().  usbnet_disconnect() mirrored that by first invoking
    unregister_netdev() and then ->unbind().
    
    Since the commit, the order in usbnet_disconnect() is reversed and no
    longer mirrors usbnet_probe().
    
    One consequence is that a PHY disconnected (and stopped) in ->unbind()
    is afterwards stopped once more by unregister_netdev() as it closes the
    netdev before unregistering.  That necessitates a contortion in ->stop()
    because the PHY may only be stopped if it hasn't already been
    disconnected.
    
    Reverting the commit allows making the call to phy_stop() unconditional
    in ->stop().
    
    Tested-by: Oleksij Rempel <o.rempel@pengutronix.de> # LAN9514/9512/9500
    Tested-by: Ferry Toth <fntoth@gmail.com> # LAN9514
    Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
    Acked-by: default avatarOliver Neukum <oneukum@suse.com>
    Cc: Martyn Welch <martyn.welch@collabora.com>
    Cc: Andrew Lunn <andrew@lunn.ch>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    d1408f6b
usbnet.c 57.9 KB