From b14e7f2ce17c6513548e910d7a8ba2a6707474fb Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 31 Mar 2016 17:22:45 +0200 Subject: [PATCH] mac80211: properly deal with station hashtable insert errors Orabug: 23331171 [ Upstream commit 62b14b241ca6f790a17ccd9dd9f62ce1b006d406 ] 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 Signed-off-by: Johannes Berg Signed-off-by: Sasha Levin (cherry picked from commit d2bccdc948e21a48d593181c05667d454f423fcd) Signed-off-by: Dan Duval --- net/mac80211/sta_info.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 2880f2ae99ab..a7027190f298 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c @@ -252,11 +252,11 @@ void sta_info_free(struct ieee80211_local *local, struct sta_info *sta) } /* Caller must hold local->sta_mtx */ -static void sta_info_hash_add(struct ieee80211_local *local, - struct sta_info *sta) +static int sta_info_hash_add(struct ieee80211_local *local, + struct sta_info *sta) { - rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, - sta_rht_params); + return rhashtable_insert_fast(&local->sta_hash, &sta->hash_node, + sta_rht_params); } static void sta_deliver_ps_frames(struct work_struct *wk) @@ -491,7 +491,9 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) set_sta_flag(sta, WLAN_STA_BLOCK_BA); /* make the station visible */ - sta_info_hash_add(local, sta); + err = sta_info_hash_add(local, sta); + if (err) + goto out_drop_sta; list_add_tail_rcu(&sta->list, &local->sta_list); @@ -526,6 +528,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) out_remove: sta_info_hash_del(local, sta); list_del_rcu(&sta->list); + out_drop_sta: local->num_sta--; synchronize_net(); __cleanup_single_sta(sta); -- 2.50.1