aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/key.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes@sipsolutions.net>2008-02-25 10:27:46 -0500
committerJohn W. Linville <linville@tuxdriver.com>2008-03-06 15:30:46 -0500
commitd0709a65181beb787ef3f58cfe45536a2bb254c8 (patch)
tree29e5f36583b0e0a3f11b291347e57672eab41dad /net/mac80211/key.c
parent5cf121c3cdb955583bf0c5d28c992b7968a4aa1a (diff)
mac80211: RCU-ify STA info structure access
This makes access to the STA hash table/list use RCU to protect against freeing of items. However, it's not a true RCU, the copy step is missing: whenever somebody changes a STA item it is simply updated. This is an existing race condition that is now somewhat understandable. This patch also fixes the race key freeing vs. STA destruction by making sure that sta_info_destroy() is always called under RTNL and frees the key. Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/key.c')
-rw-r--r--net/mac80211/key.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/mac80211/key.c b/net/mac80211/key.c
index eac9c59dbc4d..df0c04cedbe4 100644
--- a/net/mac80211/key.c
+++ b/net/mac80211/key.c
@@ -240,14 +240,17 @@ void ieee80211_key_link(struct ieee80211_key *key,
240 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) { 240 if (sdata->vif.type == IEEE80211_IF_TYPE_STA) {
241 struct sta_info *ap; 241 struct sta_info *ap;
242 242
243 rcu_read_lock();
244
243 /* same here, the AP could be using QoS */ 245 /* same here, the AP could be using QoS */
244 ap = sta_info_get(key->local, key->sdata->u.sta.bssid); 246 ap = sta_info_get(key->local, key->sdata->u.sta.bssid);
245 if (ap) { 247 if (ap) {
246 if (ap->flags & WLAN_STA_WME) 248 if (ap->flags & WLAN_STA_WME)
247 key->conf.flags |= 249 key->conf.flags |=
248 IEEE80211_KEY_FLAG_WMM_STA; 250 IEEE80211_KEY_FLAG_WMM_STA;
249 sta_info_put(ap);
250 } 251 }
252
253 rcu_read_unlock();
251 } 254 }
252 } 255 }
253 256
@@ -290,6 +293,9 @@ void ieee80211_key_free(struct ieee80211_key *key)
290 __ieee80211_key_replace(key->sdata, key->sta, 293 __ieee80211_key_replace(key->sdata, key->sta,
291 key, NULL); 294 key, NULL);
292 295
296 /*
297 * Do NOT remove this without looking at sta_info_destroy()
298 */
293 synchronize_rcu(); 299 synchronize_rcu();
294 300
295 /* 301 /*