mirror of
https://github.com/torvalds/linux.git
synced 2026-09-25 17:42:03 +02:00
wifi: mac80211: mesh: reset the CSA state when leaving
ifmsh->csa is allocated in ieee80211_mesh_csa_beacon() and only freed
in ieee80211_mesh_finish_csa(), i.e. when the channel switch completes.
Leaving the mesh while a switch is still pending therefore leaks it.
Additionally, ifmsh->csa_role and ifmsh->chsw_ttl have their state leak
in this case, so things can get mixed up in addition to the memory
leak.
Refactor the reset and call it in ieee80211_stop_mesh() to fix it all.
Assisted-by: LLM
Reported-by: syzbot+f5752cd6b94fe38be666@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f5752cd6b94fe38be666
Fixes: b8456a14e9 ("{nl,cfg,mac}80211: implement mesh channel switch userspace API")
Link: https://patch.msgid.link/20260908122838.201719-20-johannes@sipsolutions.net
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
parent
cd54bf333f
commit
860134b3af
|
|
@ -1196,6 +1196,21 @@ int ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ieee80211_mesh_reset_csa(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
struct mesh_csa_settings *csa;
|
||||
|
||||
/* Reset the TTL value and Initiator flag */
|
||||
ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
|
||||
ifmsh->chsw_ttl = 0;
|
||||
|
||||
/* Remove the CSA and MCSP elements from the beacon */
|
||||
csa = sdata_dereference(ifmsh->csa, sdata);
|
||||
RCU_INIT_POINTER(ifmsh->csa, NULL);
|
||||
kfree_rcu(csa, rcu_head);
|
||||
}
|
||||
|
||||
void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
||||
{
|
||||
struct ieee80211_local *local = sdata->local;
|
||||
|
|
@ -1206,6 +1221,7 @@ void ieee80211_stop_mesh(struct ieee80211_sub_if_data *sdata)
|
|||
|
||||
/* abort any running channel switch */
|
||||
sdata->vif.bss_conf.csa_active = false;
|
||||
ieee80211_mesh_reset_csa(sdata);
|
||||
ieee80211_vif_unblock_queues_csa(sdata);
|
||||
|
||||
/* flush STAs and mpaths on this iface */
|
||||
|
|
@ -1514,19 +1530,10 @@ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
|
|||
|
||||
int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata, u64 *changed)
|
||||
{
|
||||
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
||||
struct mesh_csa_settings *tmp_csa_settings;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
/* Reset the TTL value and Initiator flag */
|
||||
ifmsh->csa_role = IEEE80211_MESH_CSA_ROLE_NONE;
|
||||
ifmsh->chsw_ttl = 0;
|
||||
ieee80211_mesh_reset_csa(sdata);
|
||||
|
||||
/* Remove the CSA and MCSP elements from the beacon */
|
||||
tmp_csa_settings = sdata_dereference(ifmsh->csa, sdata);
|
||||
RCU_INIT_POINTER(ifmsh->csa, NULL);
|
||||
if (tmp_csa_settings)
|
||||
kfree_rcu(tmp_csa_settings, rcu_head);
|
||||
ret = ieee80211_mesh_rebuild_beacon(sdata);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user