diff options
author | Johannes Berg <johannes.berg@intel.com> | 2016-03-31 11:22:45 -0400 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2016-04-05 04:58:30 -0400 |
commit | 62b14b241ca6f790a17ccd9dd9f62ce1b006d406 (patch) | |
tree | 839a88f8cfc4599aafff36d23625b7c5f38c2836 /net | |
parent | aa507a7bc5ab7513b83fc37ed040b5254737a518 (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.c | 13 |
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 */ |
261 | static void sta_info_hash_add(struct ieee80211_local *local, | 261 | static 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 | ||
268 | static void sta_deliver_ps_frames(struct work_struct *wk) | 268 | static 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); |