--- /dev/null
+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]);
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;
}
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) {