Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

wifi: cfg80211: reject non-conformant 6 GHz center frequencies

On 6 GHz (and also 5 GHz to some degree), only a specific set of center
frequencies should be used depending on the channel bandwidth. Verify
this is the case on 6 GHz. For 5 GHz, we are more accepting as there are
APs that got it wrong historically.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://msgid.link/20240602102200.876b10a2beda.I0d3d0daea4014e99654437ff6691378dbe452652@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

authored by

Benjamin Berg and committed by
Johannes Berg
91b193d5 c1d8bd8d

+49 -11
+38
net/wireless/chan.c
··· 263 263 return nl80211_chan_width_to_mhz(c->width); 264 264 } 265 265 266 + static bool cfg80211_valid_center_freq(u32 center, 267 + enum nl80211_chan_width width) 268 + { 269 + int bw; 270 + int step; 271 + 272 + /* We only do strict verification on 6 GHz */ 273 + if (center < 5955 || center > 7115) 274 + return true; 275 + 276 + bw = nl80211_chan_width_to_mhz(width); 277 + if (bw < 0) 278 + return false; 279 + 280 + /* Validate that the channels bw is entirely within the 6 GHz band */ 281 + if (center - bw / 2 < 5945 || center + bw / 2 > 7125) 282 + return false; 283 + 284 + /* With 320 MHz the permitted channels overlap */ 285 + if (bw == 320) 286 + step = 160; 287 + else 288 + step = bw; 289 + 290 + /* 291 + * Valid channels are packed from lowest frequency towards higher ones. 292 + * So test that the lower frequency alignes with one of these steps. 293 + */ 294 + return (center - bw / 2 - 5945) % step == 0; 295 + } 296 + 266 297 bool cfg80211_chandef_valid(const struct cfg80211_chan_def *chandef) 267 298 { 268 299 u32 control_freq, oper_freq; ··· 404 373 default: 405 374 return false; 406 375 } 376 + 377 + if (!cfg80211_valid_center_freq(chandef->center_freq1, chandef->width)) 378 + return false; 379 + 380 + if (chandef->width == NL80211_CHAN_WIDTH_80P80 && 381 + !cfg80211_valid_center_freq(chandef->center_freq2, chandef->width)) 382 + return false; 407 383 408 384 /* channel 14 is only for IEEE 802.11b */ 409 385 if (chandef->center_freq1 == 2484 &&
+11 -11
net/wireless/tests/chan.c
··· 113 113 }, 114 114 }, 115 115 { 116 - .desc = "different primary 160 MHz", 116 + .desc = "different primary 320 MHz", 117 117 .c1 = { 118 118 .width = NL80211_CHAN_WIDTH_320, 119 119 .chan = &chan_6ghz_105, 120 - .center_freq1 = 6475 + 150, 120 + .center_freq1 = 6475 + 110, 121 121 }, 122 122 .c2 = { 123 123 .width = NL80211_CHAN_WIDTH_320, 124 124 .chan = &chan_6ghz_105, 125 - .center_freq1 = 6475 - 10, 125 + .center_freq1 = 6475 - 50, 126 126 }, 127 127 }, 128 128 { ··· 131 131 .c1 = { 132 132 .width = NL80211_CHAN_WIDTH_160, 133 133 .chan = &chan_6ghz_105, 134 - .center_freq1 = 6475 + 70, 134 + .center_freq1 = 6475 + 30, 135 135 }, 136 136 .c2 = { 137 137 .width = NL80211_CHAN_WIDTH_320, 138 138 .chan = &chan_6ghz_105, 139 - .center_freq1 = 6475 - 10, 139 + .center_freq1 = 6475 - 50, 140 140 }, 141 141 .compat = true, 142 142 }, ··· 145 145 .c1 = { 146 146 .width = NL80211_CHAN_WIDTH_160, 147 147 .chan = &chan_6ghz_105, 148 - .center_freq1 = 6475 + 70, 148 + .center_freq1 = 6475 + 30, 149 149 }, 150 150 .c2 = { 151 151 .width = NL80211_CHAN_WIDTH_320, 152 152 .chan = &chan_6ghz_105, 153 - .center_freq1 = 6475 - 10, 153 + .center_freq1 = 6475 - 50, 154 154 .punctured = 0xf, 155 155 }, 156 156 .compat = true, ··· 160 160 .c1 = { 161 161 .width = NL80211_CHAN_WIDTH_160, 162 162 .chan = &chan_6ghz_105, 163 - .center_freq1 = 6475 + 70, 163 + .center_freq1 = 6475 + 30, 164 164 .punctured = 0xc0, 165 165 }, 166 166 .c2 = { 167 167 .width = NL80211_CHAN_WIDTH_320, 168 168 .chan = &chan_6ghz_105, 169 - .center_freq1 = 6475 - 10, 169 + .center_freq1 = 6475 - 50, 170 170 .punctured = 0xc000, 171 171 }, 172 172 .compat = true, ··· 176 176 .c1 = { 177 177 .width = NL80211_CHAN_WIDTH_160, 178 178 .chan = &chan_6ghz_105, 179 - .center_freq1 = 6475 + 70, 179 + .center_freq1 = 6475 + 30, 180 180 .punctured = 0x80, 181 181 }, 182 182 .c2 = { 183 183 .width = NL80211_CHAN_WIDTH_320, 184 184 .chan = &chan_6ghz_105, 185 - .center_freq1 = 6475 - 10, 185 + .center_freq1 = 6475 - 50, 186 186 .punctured = 0xc000, 187 187 }, 188 188 },