diff options
Diffstat (limited to 'net/mac80211/sta_info.c')
-rw-r--r-- | net/mac80211/sta_info.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index d9e6e81ff6b2..b83870bf60fa 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
@@ -67,7 +67,8 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
67 | { | 67 | { |
68 | struct sta_info *s; | 68 | struct sta_info *s; |
69 | 69 | ||
70 | s = local->sta_hash[STA_HASH(sta->sta.addr)]; | 70 | s = rcu_dereference_protected(local->sta_hash[STA_HASH(sta->sta.addr)], |
71 | lockdep_is_held(&local->sta_lock)); | ||
71 | if (!s) | 72 | if (!s) |
72 | return -ENOENT; | 73 | return -ENOENT; |
73 | if (s == sta) { | 74 | if (s == sta) { |
@@ -76,9 +77,11 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
76 | return 0; | 77 | return 0; |
77 | } | 78 | } |
78 | 79 | ||
79 | while (s->hnext && s->hnext != sta) | 80 | while (rcu_access_pointer(s->hnext) && |
80 | s = s->hnext; | 81 | rcu_access_pointer(s->hnext) != sta) |
81 | if (s->hnext) { | 82 | s = rcu_dereference_protected(s->hnext, |
83 | lockdep_is_held(&local->sta_lock)); | ||
84 | if (rcu_access_pointer(s->hnext)) { | ||
82 | rcu_assign_pointer(s->hnext, sta->hnext); | 85 | rcu_assign_pointer(s->hnext, sta->hnext); |
83 | return 0; | 86 | return 0; |
84 | } | 87 | } |
@@ -274,7 +277,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
274 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ | 277 | #endif /* CONFIG_MAC80211_VERBOSE_DEBUG */ |
275 | 278 | ||
276 | #ifdef CONFIG_MAC80211_MESH | 279 | #ifdef CONFIG_MAC80211_MESH |
277 | sta->plink_state = PLINK_LISTEN; | 280 | sta->plink_state = NL80211_PLINK_LISTEN; |
278 | init_timer(&sta->plink_timer); | 281 | init_timer(&sta->plink_timer); |
279 | #endif | 282 | #endif |
280 | 283 | ||
@@ -652,10 +655,12 @@ static int __must_check __sta_info_destroy(struct sta_info *sta) | |||
652 | if (ret) | 655 | if (ret) |
653 | return ret; | 656 | return ret; |
654 | 657 | ||
658 | mutex_lock(&local->key_mtx); | ||
655 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) | 659 | for (i = 0; i < NUM_DEFAULT_KEYS; i++) |
656 | ieee80211_key_free(local, sta->gtk[i]); | 660 | __ieee80211_key_free(key_mtx_dereference(local, sta->gtk[i])); |
657 | if (sta->ptk) | 661 | if (sta->ptk) |
658 | ieee80211_key_free(local, sta->ptk); | 662 | __ieee80211_key_free(key_mtx_dereference(local, sta->ptk)); |
663 | mutex_unlock(&local->key_mtx); | ||
659 | 664 | ||
660 | sta->dead = true; | 665 | sta->dead = true; |
661 | 666 | ||