@@ -4269,6 +4269,7 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *rdev = info->user_ptr[0];
struct wireless_dev *wdev = info->user_ptr[1];
+ int ret;
if (!rdev->ops->del_virtual_intf)
return -EOPNOTSUPP;
@@ -4296,9 +4297,11 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
else
dev_close(wdev->netdev);
+ ret = cfg80211_remove_virtual_intf(rdev, wdev);
+
mutex_lock(&rdev->wiphy.mtx);
- return cfg80211_remove_virtual_intf(rdev, wdev);
+ return ret;
}
static int nl80211_set_noack_map(struct sk_buff *skb, struct genl_info *info)
Both nl80211_del_interface and cfg80211_netdev_notifier_call hold the same wiphy_lock, then cause deadlock. The main call stack as bellow: nl80211_del_interface() takes wiphy_lock -> cfg80211_remove_virtual_intf -> rdev_del_virtual_intf -> rdev->ops->del_virtual_intf -> cfg80211_unregister_netdevice -> cfg80211_unregister_wdev -> _cfg80211_unregister_wdev -> unregister_netdevice -> unregister_netdevice_queue -> unregister_netdevice_many -> call_netdevice_notifiers(NETDEV_UNREGISTER, dev); -> call_netdevice_notifiers_extack -> call_netdevice_notifiers_info -> raw_notifier_call_chain -> cfg80211_netdev_notifier_call -> wiphy_lock(&rdev->wiphy), _cfg80211_unregister_wdev Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver") Signed-off-by: Aran Dalton <arda@allwinnertech.com> --- net/wireless/nl80211.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)