mac80211: fix a crash triggered by CSA with AP VLAN enabled
Some checks failed
Build Kernel / Build all affected Kernels (push) Waiting to run
Build all core packages / Build all core packages for selected target (push) Has been cancelled

Fix getting the correct operating channel for stations on VLAN

Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry picked from commit ba3c6ff302)
This commit is contained in:
Felix Fietkau 2026-03-05 17:12:09 +00:00
parent c2fe6ca16d
commit 360b1c8d11
2 changed files with 41 additions and 2 deletions

View file

@ -0,0 +1,39 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Thu, 5 Mar 2026 17:04:11 +0000
Subject: [PATCH] mac80211: fix crash in ieee80211_chan_bw_change for AP_VLAN
stations
ieee80211_chan_bw_change() iterates all stations and accesses
link->reserved.oper via sta->sdata->link[link_id]. For stations on
AP_VLAN interfaces (e.g. 4addr WDS clients), sta->sdata points to
the VLAN sdata, whose link never participates in chanctx reservations.
This leaves link->reserved.oper zero-initialized with chan == NULL,
causing a NULL pointer dereference in __ieee80211_sta_cap_rx_bw()
when accessing chandef->chan->band during CSA.
Resolve the VLAN sdata to its parent AP sdata using get_bss_sdata()
before accessing link data.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -441,13 +441,15 @@ static void ieee80211_chan_bw_change(str
rcu_read_lock();
list_for_each_entry_rcu(sta, &local->sta_list,
list) {
- struct ieee80211_sub_if_data *sdata = sta->sdata;
+ struct ieee80211_sub_if_data *sdata;
enum ieee80211_sta_rx_bandwidth new_sta_bw;
unsigned int link_id;
if (!ieee80211_sdata_running(sta->sdata))
continue;
+ sdata = get_bss_sdata(sta->sdata);
+
for (link_id = 0; link_id < ARRAY_SIZE(sta->sdata->link); link_id++) {
struct ieee80211_link_data *link =
rcu_dereference(sdata->link[link_id]);

View file

@ -48,7 +48,7 @@
if (sdata->wdev.links[link_id].cac_started)
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -644,10 +644,11 @@ ieee80211_find_chanctx(struct ieee80211_
@@ -646,10 +646,11 @@ ieee80211_find_chanctx(struct ieee80211_
return NULL;
}
@ -61,7 +61,7 @@
struct ieee80211_link_data *link;
struct ieee80211_channel *chan;
int radio_idx;
@@ -658,14 +659,25 @@ bool ieee80211_is_radar_required(struct
@@ -660,14 +661,25 @@ bool ieee80211_is_radar_required(struct
return false;
for_each_sdata_link(local, link) {