mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-09-18 23:19:34 +02:00
wifi: mac80211: disconnect on CSA to channel 0
The refactor for the CSA parsing erroneously equates channel
zero and no information present, leading it to ignore a CSA
on an AP that advertises a switch to that (invalid) channel.
This leads to not disconnecting, which we should. For Intel
devices, this can lead to a firmware crash.
Fix this by using an int type for the channel number as well
as the opclass, and using a (negative) value that cannot be
encoded in the element to indicate it's not present.
Fixes: 21c3f8f955 ("wifi: mac80211: refactor STA CSA parsing flows")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Reviewed-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260802111213.3bc833515e40.I255c37c31ca8b0b34e351cf254e16b6071dd8fb3@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
This commit is contained in:
@@ -227,7 +227,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
{
|
||||
enum nl80211_band new_band = current_band;
|
||||
int new_freq;
|
||||
u8 new_chan_no = 0, new_op_class = 0;
|
||||
int new_chan_no = -1, new_op_class = -1;
|
||||
struct ieee80211_channel *new_chan;
|
||||
struct cfg80211_chan_def new_chandef = {};
|
||||
const struct ieee80211_sec_chan_offs_ie *sec_chan_offs;
|
||||
@@ -256,7 +256,7 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
new_op_class = ext_chansw_elem->new_operating_class;
|
||||
|
||||
if (!ieee80211_operating_class_to_band(new_op_class, &new_band)) {
|
||||
new_op_class = 0;
|
||||
new_op_class = -1;
|
||||
if (!unprot_action)
|
||||
sdata_info(sdata,
|
||||
"cannot understand ECSA IE operating class, %d, ignoring\n",
|
||||
@@ -268,14 +268,14 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
}
|
||||
}
|
||||
|
||||
if (!new_op_class && elems->ch_switch_ie) {
|
||||
if (new_op_class < 0 && elems->ch_switch_ie) {
|
||||
new_chan_no = elems->ch_switch_ie->new_ch_num;
|
||||
csa_ie->count = elems->ch_switch_ie->count;
|
||||
csa_ie->mode = elems->ch_switch_ie->mode;
|
||||
}
|
||||
|
||||
/* nothing here we understand */
|
||||
if (!new_chan_no)
|
||||
if (new_chan_no < 0)
|
||||
return 1;
|
||||
|
||||
/* Mesh Channel Switch Parameters Element */
|
||||
@@ -349,7 +349,8 @@ int ieee80211_parse_ch_switch_ie(struct ieee80211_sub_if_data *sdata,
|
||||
get_unaligned_le16(bwi->info.optional);
|
||||
} else if (!wide_bw_chansw_ie || !wbcs_elem_to_chandef(wide_bw_chansw_ie,
|
||||
&new_chandef)) {
|
||||
if (!ieee80211_operating_class_to_chandef(new_op_class, new_chan,
|
||||
if (new_op_class < 0 ||
|
||||
!ieee80211_operating_class_to_chandef(new_op_class, new_chan,
|
||||
&new_chandef))
|
||||
new_chandef = csa_ie->chanreq.oper;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user