From: Johannes Berg <redacted>
If ieee80211_process_adv_ttlm() disconnects, and some other
changes were also detected in the beacon, the link update
to the driver is still done, leading to use-after-free. Fix
this by returning, like other functions, whether or not the
update was accepted by the function.
Cc: <redacted>
Fixes: 702e80470a33 ("wifi: mac80211: support handling of advertised TID-to-link mapping")
Reviewed-by: Benjamin Berg <redacted>
Signed-off-by: Johannes Berg <redacted>
---
net/mac80211/mlme.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8eda8154ba3d..4e2e01d2f5d3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -7950,15 +7950,15 @@ static void ieee80211_tid_to_link_map_work(struct wiphy *wiphy,
sdata->u.mgd.ttlm_info.switch_time = 0;
}
-static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
- struct ieee802_11_elems *elems,
- u64 beacon_ts)
+static bool ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
+ struct ieee802_11_elems *elems,
+ u64 beacon_ts)
{
u8 i;
int ret;
if (!ieee80211_vif_is_mld(&sdata->vif))
- return;
+ return true;
if (!elems->ttlm_num) {
if (sdata->u.mgd.ttlm_info.switch_time) {@@ -7976,14 +7976,14 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
0);
if (ret) {
sdata_info(sdata, "Failed setting valid/dormant links\n");
- return;
+ return true;
}
ieee80211_vif_cfg_change_notify(sdata,
BSS_CHANGED_MLD_VALID_LINKS);
}
memset(&sdata->u.mgd.ttlm_info, 0,
sizeof(sdata->u.mgd.ttlm_info));
- return;
+ return true;
}
for (i = 0; i < elems->ttlm_num; i++) {@@ -7995,7 +7995,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
if (res) {
__ieee80211_disconnect(sdata);
- return;
+ return false;
}
if (ttlm_info.switch_time) {@@ -8020,7 +8020,7 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
* switch the AP will continue to announce it anyway.
*/
if (delay > IEEE80211_ADV_TTLM_ST_UNDERFLOW)
- return;
+ return true;
delay_usec = ieee80211_tu_to_usec(delay);
@@ -8039,9 +8039,11 @@ static void ieee80211_process_adv_ttlm(struct ieee80211_sub_if_data *sdata,
wiphy_hrtimer_work_queue(sdata->local->hw.wiphy,
&sdata->u.mgd.ttlm_work,
us_to_ktime(delay_usec));
- return;
+ return true;
}
}
+
+ return true;
}
static void
@@ -8535,8 +8537,9 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_link_data *link,
elems->cisco_dtpc_elem);
ieee80211_ml_reconfiguration(sdata, elems);
- ieee80211_process_adv_ttlm(sdata, elems,
- le64_to_cpu(mgmt->u.beacon.timestamp));
+ if (!ieee80211_process_adv_ttlm(sdata, elems,
+ le64_to_cpu(mgmt->u.beacon.timestamp)))
+ goto free;
apply:
ieee80211_link_info_change_notify(sdata, link, changed);
--
2.56.0