Search Linux Wireless

[PATCH 17/17] wifi: mac80211: avoid double free in auth/assoc timeout

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



In case of authentication/association timeout (as detected in
ieee80211_iface_work->ieee80211_sta_work), ieee80211_destroy_auth_data
is called.
At the beginning of it, the pointer to ifmgd::auth_data memory is
copied to a local variable.
If iface_work is queued again during the execution of the current one,
and then the driver is flushing the wiphy_works (for its needs),
ieee80211_destroy_auth_data will run again and free auth_data.
Then when the execution of the original worker continues, the previously
copied pointer will be freed, causing a kernel bug:
 kernel BUG at mm/slub.c:553! (double free)

Same for association timeout (just with ieee80211_destroy_assoc_data and
ifmgd::assoc_data)

Fix this by NULLifying auth/assoc data right after we copied
the pointer to it. That way, even in the scenario above, the code will
not handle the same timeout twice.

Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@xxxxxxxxx>
Reviewed-by: Johannes Berg <johannes.berg@xxxxxxxxx>
---
 net/mac80211/mlme.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 4d9e3e58f3cb..3ef5f82a9b87 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4507,6 +4507,8 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
 
 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
 
+	sdata->u.mgd.auth_data = NULL;
+
 	if (!assoc) {
 		/*
 		 * we are not authenticated yet, the only timer that could be
@@ -4528,7 +4530,6 @@ static void ieee80211_destroy_auth_data(struct ieee80211_sub_if_data *sdata,
 
 	cfg80211_put_bss(sdata->local->hw.wiphy, auth_data->bss);
 	kfree(auth_data);
-	sdata->u.mgd.auth_data = NULL;
 }
 
 enum assoc_status {
@@ -4545,6 +4546,8 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
 
 	lockdep_assert_wiphy(sdata->local->hw.wiphy);
 
+	sdata->u.mgd.assoc_data = NULL;
+
 	if (status != ASSOC_SUCCESS) {
 		/*
 		 * we are not associated yet, the only timer that could be
@@ -4583,7 +4586,6 @@ static void ieee80211_destroy_assoc_data(struct ieee80211_sub_if_data *sdata,
 	}
 
 	kfree(assoc_data);
-	sdata->u.mgd.assoc_data = NULL;
 }
 
 static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
-- 
2.34.1





[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Wireless Personal Area Network]     [Linux Bluetooth]     [Wireless Regulations]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux