aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2016-03-31 11:22:45 -0400
committerJohannes Berg <johannes.berg@intel.com>2016-04-05 04:58:30 -0400
commit62b14b241ca6f790a17ccd9dd9f62ce1b006d406 (patch)
tree839a88f8cfc4599aafff36d23625b7c5f38c2836 /net
parentaa507a7bc5ab7513b83fc37ed040b5254737a518 (diff)
mac80211: properly deal with station hashtable insert errors
The original hand-implemented hash-table in mac80211 couldn't result in insertion errors, and while converting to rhashtable I evidently forgot to check the errors. This surfaced now only because Ben is adding many identical keys and that resulted in hidden insertion errors. Cc: stable@vger.kernel.org Fixes: 7bedd0cfad4e1 ("mac80211: use rhashtable for station table") Reported-by: Ben Greear <greearb@candelatech.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net')
-rw-r--r--net/mac80211/sta_info.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index d20bab5c146c..18b56d7a2dbd 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -258,11 +258,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta)
258} 258}
259 259
260/* Caller must hold local->sta_mtx */ 260/* Caller must hold local->sta_mtx */
261static void sta_info_hash_add(struct ieee80211_local *local, 261static int sta_info_hash_add(struct ieee80211_local *local,
262 struct sta_info *sta) 262 struct sta_info *sta)
263{ 263{
264 rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, 264 return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node,
265 sta_rht_params); 265 sta_rht_params);
266} 266}
267 267
268static void sta_deliver_ps_frames(struct work_struct *wk) 268static void sta_deliver_ps_frames(struct work_struct *wk)
@@ -524,7 +524,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
524 set_sta_flag(sta, WLAN_STA_BLOCK_BA); 524 set_sta_flag(sta, WLAN_STA_BLOCK_BA);
525 525
526 /* make the station visible */ 526 /* make the station visible */
527 sta_info_hash_add(local, sta); 527 err = sta_info_hash_add(local, sta);
528 if (err)
529 goto out_drop_sta;
528 530
529 list_add_tail_rcu(&sta->list, &local->sta_list); 531 list_add_tail_rcu(&sta->list, &local->sta_list);
530 532
@@ -557,6 +559,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
557 out_remove: 559 out_remove:
558 sta_info_hash_del(local, sta); 560 sta_info_hash_del(local, sta);
559 list_del_rcu(&sta->list); 561 list_del_rcu(&sta->list);
562 out_drop_sta:
560 local->num_sta--; 563 local->num_sta--;
561 synchronize_net(); 564 synchronize_net();
562 __cleanup_single_sta(sta); 565 __cleanup_single_sta(sta);