cfg80211: hold reg_mutex when updating regulatory
authorSven Neumann <s.neumann@raumfeld.com>
Tue, 30 Aug 2011 21:38:53 +0000 (23:38 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 14 Sep 2011 17:26:39 +0000 (13:26 -0400)
The function wiphy_update_regulatory() uses the static variable
last_request and thus needs to be called with reg_mutex held.
This is the case for all users in reg.c, but the function was
exported for use by wiphy_register(), from where it is called
without the lock being held.

Fix this by making wiphy_update_regulatory() private and introducing
regulatory_update() as a wrapper that acquires and holds the lock.

Signed-off-by: Sven Neumann <s.neumann@raumfeld.com>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: Luis R. Rodriguez <mcgrof@gmail.com>
Cc: Daniel Mack <daniel@zonque.org>
Cc: linux-wireless@vger.kernel.org
Acked-by: Luis R. Rodriguez <mcgrof@qca.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
net/wireless/core.c
net/wireless/core.h
net/wireless/reg.c
net/wireless/reg.h

index 645437cfc464d505a3673870f8c0a6eb73287535..44cbebac25e0f001685cd2960d0fc249faff8544 100644 (file)
@@ -582,7 +582,7 @@ int wiphy_register(struct wiphy *wiphy)
        }
 
        /* set up regulatory info */
-       wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
+       regulatory_update(wiphy, NL80211_REGDOM_SET_BY_CORE);
 
        list_add_rcu(&rdev->list, &cfg80211_rdev_list);
        cfg80211_rdev_list_generation++;
index 8672e028022ffba288dc6166417aea9ae49391de..796a4bdf8b0d8901f571cc81436ab0719abbab17 100644 (file)
@@ -279,8 +279,6 @@ extern int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
                               char *newname);
 
 void ieee80211_set_bitrate_flags(struct wiphy *wiphy);
-void wiphy_update_regulatory(struct wiphy *wiphy,
-                            enum nl80211_reg_initiator setby);
 
 void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
 void cfg80211_bss_age(struct cfg80211_registered_device *dev,
index a2b09c2df1bf8cefa0ff380e6fb72430ac7063d6..a1f069da79a40265d194270d126c20f914353b93 100644 (file)
@@ -101,6 +101,9 @@ struct reg_beacon {
        struct ieee80211_channel chan;
 };
 
+static void wiphy_update_regulatory(struct wiphy *wiphy,
+                                   enum nl80211_reg_initiator initiator);
+
 static void reg_todo(struct work_struct *work);
 static DECLARE_WORK(reg_work, reg_todo);
 
@@ -1118,11 +1121,13 @@ static void reg_process_ht_flags(struct wiphy *wiphy)
 
 }
 
-void wiphy_update_regulatory(struct wiphy *wiphy,
-                            enum nl80211_reg_initiator initiator)
+static void wiphy_update_regulatory(struct wiphy *wiphy,
+                                   enum nl80211_reg_initiator initiator)
 {
        enum ieee80211_band band;
 
+       assert_reg_lock();
+
        if (ignore_reg_update(wiphy, initiator))
                return;
 
@@ -1137,6 +1142,14 @@ void wiphy_update_regulatory(struct wiphy *wiphy,
                wiphy->reg_notifier(wiphy, last_request);
 }
 
+void regulatory_update(struct wiphy *wiphy,
+                      enum nl80211_reg_initiator setby)
+{
+       mutex_lock(&reg_mutex);
+       wiphy_update_regulatory(wiphy, setby);
+       mutex_unlock(&reg_mutex);
+}
+
 static void handle_channel_custom(struct wiphy *wiphy,
                                  enum ieee80211_band band,
                                  unsigned int chan_idx,
index b67d1c3a2fb954eac3d282a4a9cf4ac5e1231670..4a56799d868d5fa7efc48ab8e21cbb67d3a8a473 100644 (file)
@@ -16,6 +16,8 @@ void regulatory_exit(void);
 
 int set_regdom(const struct ieee80211_regdomain *rd);
 
+void regulatory_update(struct wiphy *wiphy, enum nl80211_reg_initiator setby);
+
 /**
  * regulatory_hint_found_beacon - hints a beacon was found on a channel
  * @wiphy: the wireless device where the beacon was found on