All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2] cfg80211: fix netdev registration deadlock
@ 2021-02-01 18:20 Johannes Berg
  0 siblings, 0 replies; only message in thread
From: Johannes Berg @ 2021-02-01 18:20 UTC (permalink / raw)
  To: linux-wireless; +Cc: Johannes Berg, syzbot+2ae0ca9d7737ad1a62b7

From: Johannes Berg <johannes.berg@intel.com>

If register_netdevice() fails after having called cfg80211's
netdev notifier (cfg80211_netdev_notifier_call) it will call
the notifier again with UNREGISTER. This would then lock the
wiphy mutex because we're marked as registered, which causes
a deadlock.

Fix this by separately keeping track of whether or not we're
in the middle of registering to also skip the notifier call
on this unregister.

Reported-by: syzbot+2ae0ca9d7737ad1a62b7@syzkaller.appspotmail.com
Fixes: a05829a7222e ("cfg80211: avoid holding the RTNL when calling the driver")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/cfg80211.h | 4 +++-
 net/wireless/core.c    | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 4741d71ead21..4cdd75449d73 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5299,6 +5299,8 @@ static inline void wiphy_unlock(struct wiphy *wiphy)
  * @wiphy: pointer to hardware description
  * @iftype: interface type
  * @registered: is this wdev already registered with cfg80211
+ * @registering: indicates we're doing registration under wiphy lock
+ *	for the notifier
  * @list: (private) Used to collect the interfaces
  * @netdev: (private) Used to reference back to the netdev, may be %NULL
  * @identifier: (private) Identifier used in nl80211 to identify this
@@ -5382,7 +5384,7 @@ struct wireless_dev {
 
 	struct mutex mtx;
 
-	bool use_4addr, is_running, registered;
+	bool use_4addr, is_running, registered, registering;
 
 	u8 address[ETH_ALEN] __aligned(sizeof(u16));
 
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 18f9a5c214b5..a2785379df6e 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1346,6 +1346,7 @@ int cfg80211_register_netdevice(struct net_device *dev)
 
 	/* we'll take care of this */
 	wdev->registered = true;
+	wdev->registering = true;
 	ret = register_netdevice(dev);
 	if (ret)
 		goto out;
@@ -1361,6 +1362,7 @@ int cfg80211_register_netdevice(struct net_device *dev)
 	cfg80211_register_wdev(rdev, wdev);
 	ret = 0;
 out:
+	wdev->registering = false;
 	if (ret)
 		wdev->registered = false;
 	return ret;
@@ -1403,7 +1405,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
 		 * It is possible to get NETDEV_UNREGISTER multiple times,
 		 * so check wdev->registered.
 		 */
-		if (wdev->registered) {
+		if (wdev->registered && !wdev->registering) {
 			wiphy_lock(&rdev->wiphy);
 			_cfg80211_unregister_wdev(wdev, false);
 			wiphy_unlock(&rdev->wiphy);
-- 
2.26.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-02-01 18:24 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-01 18:20 [PATCH v2] cfg80211: fix netdev registration deadlock Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.