mirror of
https://github.com/FEX-Emu/linux.git
synced 2025-03-03 01:57:14 +00:00
virt_wifi: fix deadlock on RTNL
Fix a regression where everything in virt_wifi would just hang. This happened due to overlapping changes between commit a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") which had originally needed to change the locking, but then I introduced commit 2fe8ef106238 ("cfg80211: change netdev registration/unregistration semantics") instead. virt_wifi somehow fell through the cracks when I undid all the previous locking changes. Fix it now. Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") Reported-by: syzbot+3d2d5e6cc3fb15c6a0fd@syzkaller.appspotmail.com Link: https://lore.kernel.org/r/20210127215941.2d6a97b09784.I4f1fac32f67045171be50931f44d77e150911bee@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
a05829a722
commit
38ec7c6b6b
@ -537,9 +537,7 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
|
||||
dev->ieee80211_ptr->iftype = NL80211_IFTYPE_STATION;
|
||||
dev->ieee80211_ptr->wiphy = common_wiphy;
|
||||
|
||||
wiphy_lock(common_wiphy);
|
||||
err = register_netdevice(dev);
|
||||
wiphy_unlock(common_wiphy);
|
||||
if (err) {
|
||||
dev_err(&priv->lowerdev->dev, "can't register_netdevice: %d\n",
|
||||
err);
|
||||
@ -562,9 +560,7 @@ static int virt_wifi_newlink(struct net *src_net, struct net_device *dev,
|
||||
|
||||
return 0;
|
||||
unregister_netdev:
|
||||
wiphy_lock(common_wiphy);
|
||||
unregister_netdevice(dev);
|
||||
wiphy_unlock(common_wiphy);
|
||||
free_wireless_dev:
|
||||
kfree(dev->ieee80211_ptr);
|
||||
dev->ieee80211_ptr = NULL;
|
||||
@ -590,9 +586,7 @@ static void virt_wifi_dellink(struct net_device *dev,
|
||||
netdev_rx_handler_unregister(priv->lowerdev);
|
||||
netdev_upper_dev_unlink(priv->lowerdev, dev);
|
||||
|
||||
wiphy_lock(common_wiphy);
|
||||
unregister_netdevice_queue(dev, head);
|
||||
wiphy_unlock(common_wiphy);
|
||||
module_put(THIS_MODULE);
|
||||
|
||||
/* Deleting the wiphy is handled in the module destructor. */
|
||||
@ -631,9 +625,7 @@ static int virt_wifi_event(struct notifier_block *this, unsigned long event,
|
||||
upper_dev = priv->upperdev;
|
||||
|
||||
upper_dev->rtnl_link_ops->dellink(upper_dev, &list_kill);
|
||||
wiphy_lock(common_wiphy);
|
||||
unregister_netdevice_many(&list_kill);
|
||||
wiphy_unlock(common_wiphy);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user