2014-08-19 09:36:03

by Tomasz Bursztyka

[permalink] [raw]
Subject: [PATCH v3] cfg80211: Reorder wiphy_register/unregister() notifications relevantly

Currently it can send regulatory domain change notification before any
NEW_WIPHY notification. Moreover, if rfill_register() fails, calling
wiphy_unregister() will send a DEL_WIPHY though no NEW_WIPHY had been
sent previously.

Thus reordering so it properly notifies NEW_WIPHY before any other.

Signed-off-by: Tomasz Bursztyka <[email protected]>
---

Reusing "registered" marker to know whether it sent NEW_WIPHY yet or not.
Thus if wiphy_unregister() is called du to rfkill registration failure, it
won't send DEL_WIPHY.

net/wireless/core.c | 33 +++++++++++++++++++--------------
1 file changed, 19 insertions(+), 14 deletions(-)

diff --git a/net/wireless/core.c b/net/wireless/core.c
index afee5e0..08162e8 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -635,6 +635,21 @@ int wiphy_register(struct wiphy *wiphy)
if (IS_ERR(rdev->wiphy.debugfsdir))
rdev->wiphy.debugfsdir = NULL;

+ cfg80211_debugfs_rdev_add(rdev);
+ rtnl_unlock();
+
+ res = rfkill_register(rdev->rfkill);
+ if (res) {
+ rfkill_destroy(rdev->rfkill);
+ rdev->rfkill = NULL;
+ wiphy_unregister(&rdev->wiphy);
+ return res;
+ }
+
+ rtnl_lock();
+
+ nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
+
if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
struct regulatory_request request;

@@ -646,21 +661,9 @@ int wiphy_register(struct wiphy *wiphy)
nl80211_send_reg_change_event(&request);
}

- cfg80211_debugfs_rdev_add(rdev);
-
rdev->wiphy.registered = true;
rtnl_unlock();

- res = rfkill_register(rdev->rfkill);
- if (res) {
- rfkill_destroy(rdev->rfkill);
- rdev->rfkill = NULL;
- wiphy_unregister(&rdev->wiphy);
- return res;
- }
-
- nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
-
return 0;
}
EXPORT_SYMBOL(wiphy_register);
@@ -699,8 +702,10 @@ void wiphy_unregister(struct wiphy *wiphy)
rfkill_unregister(rdev->rfkill);

rtnl_lock();
- nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
- rdev->wiphy.registered = false;
+ if (rdev->wiphy.registered) {
+ nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);
+ rdev->wiphy.registered = false;
+ }

WARN_ON(!list_empty(&rdev->wdev_list));

--
1.8.5.5



2014-08-29 11:28:59

by Tomasz Bursztyka

[permalink] [raw]
Subject: Re: [PATCH v3] cfg80211: Reorder wiphy_register/unregister() notifications relevantly

Hi Johannes,

>> >+ cfg80211_debugfs_rdev_add(rdev);
>> >+ rtnl_unlock();
> I'm not convinced that it's safe to drop the rtnl here, when we only
> later set wiphy.registered = true.
>
> As is, the wiphy would end up on the list, but not registered - yet in
> this period it would be reachable for example for nl80211 commands in
> the unregistered state. This seems wrong.

Ok, I counted on the fact the device is not yet advertized as being
ready (the NEW_WIPHY below).
Will see how to avoid this early unlock.

> Additionally, maybe add a brief note regarding the second part of the
> patch (checking registered in unregister) to the commit log?

Sure.

Tomasz

2014-08-29 11:10:30

by Johannes Berg

[permalink] [raw]
Subject: Re: [PATCH v3] cfg80211: Reorder wiphy_register/unregister() notifications relevantly

On Tue, 2014-08-19 at 12:35 +0300, Tomasz Bursztyka wrote:

> + cfg80211_debugfs_rdev_add(rdev);
> + rtnl_unlock();

I'm not convinced that it's safe to drop the rtnl here, when we only
later set wiphy.registered = true.

As is, the wiphy would end up on the list, but not registered - yet in
this period it would be reachable for example for nl80211 commands in
the unregistered state. This seems wrong.

Additionally, maybe add a brief note regarding the second part of the
patch (checking registered in unregister) to the commit log?

johannes