cfg80211/mac80211: correct qos-map locking
authorJohannes Berg <johannes.berg@intel.com>
Mon, 30 Dec 2013 22:12:37 +0000 (23:12 +0100)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 30 Dec 2013 22:14:03 +0000 (23:14 +0100)
Since the RTNL can't always be held, use wdev/sdata locking for
the qos-map dereference in mac80211. This requires cfg80211 to
consistently lock it, which it was missing in one place.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/cfg.c
net/wireless/util.c

index 09d2e58a2ba70e50ff6489700565a3755358a3b0..fd1020e791d836ae1c8d666c6820bc9c7eb3aff2 100644 (file)
@@ -3854,7 +3854,7 @@ static int ieee80211_set_qos_map(struct wiphy *wiphy,
                new_qos_map = NULL;
        }
 
-       old_qos_map = rtnl_dereference(sdata->qos_map);
+       old_qos_map = sdata_dereference(sdata->qos_map, sdata);
        rcu_assign_pointer(sdata->qos_map, new_qos_map);
        if (old_qos_map)
                kfree_rcu(old_qos_map, rcu_head);
index 5618888853b24ffdac2853509a1528f70ac1661b..329b0efb3ded27b244950e8ff1fab9b322687442 100644 (file)
@@ -879,7 +879,9 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev,
 
                dev->ieee80211_ptr->use_4addr = false;
                dev->ieee80211_ptr->mesh_id_up_len = 0;
+               wdev_lock(dev->ieee80211_ptr);
                rdev_set_qos_map(rdev, dev, NULL);
+               wdev_unlock(dev->ieee80211_ptr);
 
                switch (otype) {
                case NL80211_IFTYPE_AP: