1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright 2002-2005, Instant802 Networks, Inc. 4 * Copyright 2005-2006, Devicescape Software, Inc. 5 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> 6 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net> 7 * Copyright 2013-2014 Intel Mobile Communications GmbH 8 * Copyright (C) 2015-2017 Intel Deutschland GmbH 9 * Copyright (C) 2018-2026 Intel Corporation 10 * 11 * element parsing for mac80211 12 */ 13 14 #include <net/mac80211.h> 15 #include <linux/netdevice.h> 16 #include <linux/export.h> 17 #include <linux/types.h> 18 #include <linux/slab.h> 19 #include <linux/skbuff.h> 20 #include <linux/etherdevice.h> 21 #include <linux/if_arp.h> 22 #include <linux/bitmap.h> 23 #include <linux/crc32.h> 24 #include <net/net_namespace.h> 25 #include <net/cfg80211.h> 26 #include <net/rtnetlink.h> 27 #include <kunit/visibility.h> 28 29 #include "ieee80211_i.h" 30 #include "driver-ops.h" 31 #include "rate.h" 32 #include "mesh.h" 33 #include "wme.h" 34 #include "led.h" 35 #include "wep.h" 36 37 struct ieee80211_elems_parse { 38 /* must be first for kfree to work */ 39 struct ieee802_11_elems elems; 40 41 /* The basic Multi-Link element in the original elements */ 42 const struct element *ml_basic_elem; 43 44 /* The reconfiguration Multi-Link element in the original elements */ 45 const struct element *ml_reconf_elem; 46 47 /* The EPCS Multi-Link element in the original elements */ 48 const struct element *ml_epcs_elem; 49 50 bool multi_link_inner; 51 bool skip_vendor; 52 53 /* 54 * scratch buffer that can be used for various element parsing related 55 * tasks, e.g., element de-fragmentation etc. 56 */ 57 size_t scratch_len; 58 u8 *scratch_pos; 59 u8 scratch[] __counted_by(scratch_len); 60 }; 61 62 static void 63 ieee80211_parse_extension_element(u32 *crc, 64 const struct element *elem, 65 struct ieee80211_elems_parse *elems_parse, 66 struct ieee80211_elems_parse_params *params) 67 { 68 struct ieee802_11_elems *elems = &elems_parse->elems; 69 const void *data = elem->data + 1; 70 bool calc_crc = false; 71 u8 len; 72 73 if (!elem->datalen) 74 return; 75 76 len = elem->datalen - 1; 77 78 switch (elem->data[0]) { 79 case WLAN_EID_EXT_HE_MU_EDCA: 80 if (params->mode < IEEE80211_CONN_MODE_HE) 81 break; 82 calc_crc = true; 83 if (len >= sizeof(*elems->mu_edca_param_set)) 84 elems->mu_edca_param_set = data; 85 break; 86 case WLAN_EID_EXT_HE_CAPABILITY: 87 if (params->mode < IEEE80211_CONN_MODE_HE) 88 break; 89 if (ieee80211_he_capa_size_ok(data, len)) { 90 elems->he_cap = data; 91 elems->he_cap_len = len; 92 } 93 break; 94 case WLAN_EID_EXT_HE_OPERATION: 95 if (params->mode < IEEE80211_CONN_MODE_HE) 96 break; 97 calc_crc = true; 98 if (len >= sizeof(*elems->he_operation) && 99 len >= ieee80211_he_oper_size(data) - 1) 100 elems->he_operation = data; 101 break; 102 case WLAN_EID_EXT_UORA: 103 if (params->mode < IEEE80211_CONN_MODE_HE) 104 break; 105 if (len >= 1) 106 elems->uora_element = data; 107 break; 108 case WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME: 109 if (len == 3) 110 elems->max_channel_switch_time = data; 111 break; 112 case WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION: 113 if (len >= sizeof(*elems->mbssid_config_ie)) 114 elems->mbssid_config_ie = data; 115 break; 116 case WLAN_EID_EXT_HE_SPR: 117 if (params->mode < IEEE80211_CONN_MODE_HE) 118 break; 119 if (len >= sizeof(*elems->he_spr) && 120 len >= ieee80211_he_spr_size(data) - 1) 121 elems->he_spr = data; 122 break; 123 case WLAN_EID_EXT_HE_6GHZ_CAPA: 124 if (params->mode < IEEE80211_CONN_MODE_HE) 125 break; 126 if (len >= sizeof(*elems->he_6ghz_capa)) 127 elems->he_6ghz_capa = data; 128 break; 129 case WLAN_EID_EXT_EHT_CAPABILITY: 130 if (params->mode < IEEE80211_CONN_MODE_EHT) 131 break; 132 if (ieee80211_eht_capa_size_ok(elems->he_cap, 133 data, len, 134 params->from_ap)) { 135 elems->eht_cap = data; 136 elems->eht_cap_len = len; 137 } 138 break; 139 case WLAN_EID_EXT_EHT_OPERATION: 140 if (params->mode < IEEE80211_CONN_MODE_EHT) 141 break; 142 if (ieee80211_eht_oper_size_ok(data, len)) 143 elems->eht_operation = data; 144 calc_crc = true; 145 break; 146 case WLAN_EID_EXT_EHT_MULTI_LINK: 147 if (params->mode < IEEE80211_CONN_MODE_EHT) 148 break; 149 calc_crc = true; 150 151 if (ieee80211_mle_size_ok(data, len)) { 152 const struct ieee80211_multi_link_elem *mle = 153 (void *)data; 154 155 switch (le16_get_bits(mle->control, 156 IEEE80211_ML_CONTROL_TYPE)) { 157 case IEEE80211_ML_CONTROL_TYPE_BASIC: 158 if (elems_parse->multi_link_inner) { 159 elems->parse_error |= 160 IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC; 161 break; 162 } 163 break; 164 case IEEE80211_ML_CONTROL_TYPE_RECONF: 165 elems_parse->ml_reconf_elem = elem; 166 break; 167 case IEEE80211_ML_CONTROL_TYPE_PRIO_ACCESS: 168 elems_parse->ml_epcs_elem = elem; 169 break; 170 default: 171 break; 172 } 173 } 174 break; 175 case WLAN_EID_EXT_BANDWIDTH_INDICATION: 176 if (params->mode < IEEE80211_CONN_MODE_EHT) 177 break; 178 if (ieee80211_bandwidth_indication_size_ok(data, len)) 179 elems->bandwidth_indication = data; 180 calc_crc = true; 181 break; 182 case WLAN_EID_EXT_TID_TO_LINK_MAPPING: 183 if (params->mode < IEEE80211_CONN_MODE_EHT) 184 break; 185 calc_crc = true; 186 if (ieee80211_tid_to_link_map_size_ok(data, len) && 187 elems->ttlm_num < ARRAY_SIZE(elems->ttlm)) { 188 elems->ttlm[elems->ttlm_num] = (void *)data; 189 elems->ttlm_num++; 190 } 191 break; 192 case WLAN_EID_EXT_UHR_OPER: 193 if (params->mode < IEEE80211_CONN_MODE_UHR) 194 break; 195 calc_crc = true; 196 if (ieee80211_uhr_oper_size_ok(data, len, 197 params->type == (IEEE80211_FTYPE_MGMT | 198 IEEE80211_STYPE_BEACON))) { 199 elems->uhr_operation = data; 200 elems->uhr_operation_len = len; 201 } 202 break; 203 case WLAN_EID_EXT_UHR_CAPA: 204 if (params->mode < IEEE80211_CONN_MODE_UHR) 205 break; 206 calc_crc = true; 207 if (ieee80211_uhr_capa_size_ok(data, len, true)) { 208 elems->uhr_cap = data; 209 elems->uhr_cap_len = len; 210 } 211 break; 212 } 213 214 if (crc && calc_crc) 215 *crc = crc32_be(*crc, (void *)elem, elem->datalen + 2); 216 } 217 218 static void ieee80211_parse_tpe(struct ieee80211_parsed_tpe *tpe, 219 const u8 *data, u8 len) 220 { 221 const struct ieee80211_tx_pwr_env *env = (const void *)data; 222 u8 count, interpret, category; 223 u8 *out, N, *cnt_out = NULL, *N_out = NULL; 224 225 if (!ieee80211_valid_tpe_element(data, len)) 226 return; 227 228 count = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_COUNT); 229 interpret = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_INTERPRET); 230 category = u8_get_bits(env->info, IEEE80211_TX_PWR_ENV_INFO_CATEGORY); 231 232 switch (interpret) { 233 case IEEE80211_TPE_LOCAL_EIRP: 234 out = tpe->max_local[category].power; 235 cnt_out = &tpe->max_local[category].count; 236 tpe->max_local[category].valid = true; 237 break; 238 case IEEE80211_TPE_REG_CLIENT_EIRP: 239 out = tpe->max_reg_client[category].power; 240 cnt_out = &tpe->max_reg_client[category].count; 241 tpe->max_reg_client[category].valid = true; 242 break; 243 case IEEE80211_TPE_LOCAL_EIRP_PSD: 244 out = tpe->psd_local[category].power; 245 cnt_out = &tpe->psd_local[category].count; 246 N_out = &tpe->psd_local[category].n; 247 tpe->psd_local[category].valid = true; 248 break; 249 case IEEE80211_TPE_REG_CLIENT_EIRP_PSD: 250 out = tpe->psd_reg_client[category].power; 251 cnt_out = &tpe->psd_reg_client[category].count; 252 N_out = &tpe->psd_reg_client[category].n; 253 tpe->psd_reg_client[category].valid = true; 254 break; 255 } 256 257 switch (interpret) { 258 case IEEE80211_TPE_LOCAL_EIRP: 259 case IEEE80211_TPE_REG_CLIENT_EIRP: 260 /* count was validated <= 3, plus 320 MHz */ 261 BUILD_BUG_ON(IEEE80211_TPE_EIRP_ENTRIES_320MHZ < 5); 262 memcpy(out, env->variable, count + 1); 263 *cnt_out = count + 1; 264 /* separately take 320 MHz if present */ 265 if (count == 3 && len > sizeof(*env) + count + 1) { 266 out[4] = env->variable[4]; 267 *cnt_out = 5; 268 } 269 break; 270 case IEEE80211_TPE_LOCAL_EIRP_PSD: 271 case IEEE80211_TPE_REG_CLIENT_EIRP_PSD: 272 if (!count) { 273 memset(out, env->variable[0], 274 IEEE80211_TPE_PSD_ENTRIES_320MHZ); 275 *cnt_out = IEEE80211_TPE_PSD_ENTRIES_320MHZ; 276 break; 277 } 278 279 N = 1 << (count - 1); 280 memcpy(out, env->variable, N); 281 *cnt_out = N; 282 *N_out = N; 283 284 if (len > sizeof(*env) + N) { 285 int K = u8_get_bits(env->variable[N], 286 IEEE80211_TX_PWR_ENV_EXT_COUNT); 287 288 K = min(K, IEEE80211_TPE_PSD_ENTRIES_320MHZ - N); 289 memcpy(out + N, env->variable + N + 1, K); 290 (*cnt_out) += K; 291 } 292 break; 293 } 294 } 295 296 static u32 297 _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, 298 struct ieee80211_elems_parse *elems_parse, 299 const struct element *check_inherit) 300 { 301 struct ieee802_11_elems *elems = &elems_parse->elems; 302 const struct element *elem; 303 bool calc_crc = params->filter != 0; 304 DECLARE_BITMAP(seen_elems, 256); 305 u32 crc = params->crc; 306 307 bitmap_zero(seen_elems, 256); 308 309 switch (params->type) { 310 /* we don't need to parse assoc request, luckily (it's value 0) */ 311 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_REQ: 312 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_REQ: 313 default: 314 WARN(1, "invalid frame type 0x%x for element parsing\n", 315 params->type); 316 break; 317 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ASSOC_RESP: 318 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_REASSOC_RESP: 319 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_REQ: 320 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_PROBE_RESP: 321 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON: 322 case IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_ACTION: 323 case IEEE80211_FTYPE_EXT | IEEE80211_STYPE_S1G_BEACON: 324 break; 325 } 326 327 for_each_element(elem, params->start, params->len) { 328 const struct element *subelem; 329 u8 elem_parse_failed; 330 u8 id = elem->id; 331 u8 elen = elem->datalen; 332 const u8 *pos = elem->data; 333 334 if (check_inherit && 335 !cfg80211_is_element_inherited(elem, 336 check_inherit)) 337 continue; 338 339 switch (id) { 340 case WLAN_EID_SSID: 341 case WLAN_EID_SUPP_RATES: 342 case WLAN_EID_FH_PARAMS: 343 case WLAN_EID_DS_PARAMS: 344 case WLAN_EID_CF_PARAMS: 345 case WLAN_EID_TIM: 346 case WLAN_EID_IBSS_PARAMS: 347 case WLAN_EID_CHALLENGE: 348 case WLAN_EID_RSN: 349 case WLAN_EID_ERP_INFO: 350 case WLAN_EID_EXT_SUPP_RATES: 351 case WLAN_EID_HT_CAPABILITY: 352 case WLAN_EID_HT_OPERATION: 353 case WLAN_EID_VHT_CAPABILITY: 354 case WLAN_EID_VHT_OPERATION: 355 case WLAN_EID_MESH_ID: 356 case WLAN_EID_MESH_CONFIG: 357 case WLAN_EID_PEER_MGMT: 358 case WLAN_EID_PREQ: 359 case WLAN_EID_PREP: 360 case WLAN_EID_PERR: 361 case WLAN_EID_RANN: 362 case WLAN_EID_CHANNEL_SWITCH: 363 case WLAN_EID_EXT_CHANSWITCH_ANN: 364 case WLAN_EID_COUNTRY: 365 case WLAN_EID_PWR_CONSTRAINT: 366 case WLAN_EID_TIMEOUT_INTERVAL: 367 case WLAN_EID_SECONDARY_CHANNEL_OFFSET: 368 case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: 369 case WLAN_EID_CHAN_SWITCH_PARAM: 370 case WLAN_EID_EXT_CAPABILITY: 371 case WLAN_EID_CHAN_SWITCH_TIMING: 372 case WLAN_EID_LINK_ID: 373 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 374 case WLAN_EID_RSNX: 375 case WLAN_EID_S1G_BCN_COMPAT: 376 case WLAN_EID_S1G_CAPABILITIES: 377 case WLAN_EID_S1G_OPERATION: 378 case WLAN_EID_AID_RESPONSE: 379 case WLAN_EID_S1G_SHORT_BCN_INTERVAL: 380 /* 381 * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible 382 * that if the content gets bigger it might be needed more than once 383 */ 384 if (test_bit(id, seen_elems)) { 385 elems->parse_error |= 386 IEEE80211_PARSE_ERR_DUP_ELEM; 387 continue; 388 } 389 break; 390 } 391 392 if (calc_crc && id < 64 && (params->filter & (1ULL << id))) 393 crc = crc32_be(crc, pos - 2, elen + 2); 394 395 elem_parse_failed = 0; 396 397 switch (id) { 398 case WLAN_EID_LINK_ID: 399 if (elen + 2 < sizeof(struct ieee80211_tdls_lnkie)) { 400 elem_parse_failed = 401 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 402 break; 403 } 404 elems->lnk_id = (void *)(pos - 2); 405 break; 406 case WLAN_EID_CHAN_SWITCH_TIMING: 407 if (elen < sizeof(struct ieee80211_ch_switch_timing)) { 408 elem_parse_failed = 409 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 410 break; 411 } 412 elems->ch_sw_timing = (void *)pos; 413 break; 414 case WLAN_EID_EXT_CAPABILITY: 415 elems->ext_capab = pos; 416 elems->ext_capab_len = elen; 417 break; 418 case WLAN_EID_SSID: 419 elems->ssid = pos; 420 elems->ssid_len = elen; 421 break; 422 case WLAN_EID_SUPP_RATES: 423 elems->supp_rates = pos; 424 elems->supp_rates_len = elen; 425 break; 426 case WLAN_EID_DS_PARAMS: 427 if (elen >= 1) 428 elems->ds_params = pos; 429 else 430 elem_parse_failed = 431 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 432 break; 433 case WLAN_EID_TIM: 434 if (elen >= sizeof(struct ieee80211_tim_ie)) { 435 elems->tim = (void *)pos; 436 elems->tim_len = elen; 437 } else 438 elem_parse_failed = 439 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 440 break; 441 case WLAN_EID_VENDOR_SPECIFIC: 442 if (elems_parse->skip_vendor) 443 break; 444 445 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 446 pos[2] == 0xf2) { 447 /* Microsoft OUI (00:50:F2) */ 448 449 if (calc_crc) 450 crc = crc32_be(crc, pos - 2, elen + 2); 451 452 if (elen >= 5 && pos[3] == 2) { 453 /* OUI Type 2 - WMM IE */ 454 if (pos[4] == 0) { 455 elems->wmm_info = pos; 456 elems->wmm_info_len = elen; 457 } else if (pos[4] == 1) { 458 elems->wmm_param = pos; 459 elems->wmm_param_len = elen; 460 } 461 } 462 } 463 break; 464 case WLAN_EID_RSN: 465 elems->rsn = pos; 466 elems->rsn_len = elen; 467 break; 468 case WLAN_EID_ERP_INFO: 469 if (elen >= 1) 470 elems->erp_info = pos; 471 else 472 elem_parse_failed = 473 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 474 break; 475 case WLAN_EID_EXT_SUPP_RATES: 476 elems->ext_supp_rates = pos; 477 elems->ext_supp_rates_len = elen; 478 break; 479 case WLAN_EID_HT_CAPABILITY: 480 if (params->mode < IEEE80211_CONN_MODE_HT) 481 break; 482 if (elen >= sizeof(struct ieee80211_ht_cap)) 483 elems->ht_cap_elem = (void *)pos; 484 else 485 elem_parse_failed = 486 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 487 break; 488 case WLAN_EID_HT_OPERATION: 489 if (params->mode < IEEE80211_CONN_MODE_HT) 490 break; 491 if (elen >= sizeof(struct ieee80211_ht_operation)) 492 elems->ht_operation = (void *)pos; 493 else 494 elem_parse_failed = 495 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 496 break; 497 case WLAN_EID_VHT_CAPABILITY: 498 if (params->mode < IEEE80211_CONN_MODE_VHT) 499 break; 500 if (elen >= sizeof(struct ieee80211_vht_cap)) 501 elems->vht_cap_elem = (void *)pos; 502 else 503 elem_parse_failed = 504 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 505 break; 506 case WLAN_EID_VHT_OPERATION: 507 if (params->mode < IEEE80211_CONN_MODE_VHT) 508 break; 509 if (elen >= sizeof(struct ieee80211_vht_operation)) { 510 elems->vht_operation = (void *)pos; 511 if (calc_crc) 512 crc = crc32_be(crc, pos - 2, elen + 2); 513 break; 514 } 515 elem_parse_failed = 516 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 517 break; 518 case WLAN_EID_OPMODE_NOTIF: 519 if (params->mode < IEEE80211_CONN_MODE_VHT) 520 break; 521 if (elen > 0) { 522 elems->opmode_notif = pos; 523 if (calc_crc) 524 crc = crc32_be(crc, pos - 2, elen + 2); 525 break; 526 } 527 elem_parse_failed = 528 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 529 break; 530 case WLAN_EID_MESH_ID: 531 elems->mesh_id = pos; 532 elems->mesh_id_len = elen; 533 break; 534 case WLAN_EID_MESH_CONFIG: 535 if (elen >= sizeof(struct ieee80211_meshconf_ie)) 536 elems->mesh_config = (void *)pos; 537 else 538 elem_parse_failed = 539 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 540 break; 541 case WLAN_EID_PEER_MGMT: 542 elems->peering = pos; 543 elems->peering_len = elen; 544 break; 545 case WLAN_EID_MESH_AWAKE_WINDOW: 546 if (elen >= 2) 547 elems->awake_window = (void *)pos; 548 break; 549 case WLAN_EID_PREQ: 550 elems->preq = pos; 551 elems->preq_len = elen; 552 break; 553 case WLAN_EID_PREP: 554 elems->prep = pos; 555 elems->prep_len = elen; 556 break; 557 case WLAN_EID_PERR: 558 elems->perr = pos; 559 elems->perr_len = elen; 560 break; 561 case WLAN_EID_RANN: 562 if (elen >= sizeof(struct ieee80211_rann_ie)) 563 elems->rann = (void *)pos; 564 else 565 elem_parse_failed = 566 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 567 break; 568 case WLAN_EID_CHANNEL_SWITCH: 569 if (elen != sizeof(struct ieee80211_channel_sw_ie)) { 570 elem_parse_failed = 571 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 572 break; 573 } 574 elems->ch_switch_ie = (void *)pos; 575 break; 576 case WLAN_EID_EXT_CHANSWITCH_ANN: 577 if (elen != sizeof(struct ieee80211_ext_chansw_ie)) { 578 elem_parse_failed = 579 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 580 break; 581 } 582 elems->ext_chansw_ie = (void *)pos; 583 break; 584 case WLAN_EID_SECONDARY_CHANNEL_OFFSET: 585 if (params->mode < IEEE80211_CONN_MODE_HT) 586 break; 587 if (elen != sizeof(struct ieee80211_sec_chan_offs_ie)) { 588 elem_parse_failed = 589 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 590 break; 591 } 592 elems->sec_chan_offs = (void *)pos; 593 break; 594 case WLAN_EID_CHAN_SWITCH_PARAM: 595 if (elen < 596 sizeof(*elems->mesh_chansw_params_ie)) { 597 elem_parse_failed = 598 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 599 break; 600 } 601 elems->mesh_chansw_params_ie = (void *)pos; 602 break; 603 case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: 604 if (params->mode < IEEE80211_CONN_MODE_VHT) 605 break; 606 607 if (params->type != (IEEE80211_FTYPE_MGMT | 608 IEEE80211_STYPE_ACTION)) { 609 elem_parse_failed = 610 IEEE80211_PARSE_ERR_UNEXPECTED_ELEM; 611 break; 612 } 613 614 if (elen < sizeof(*elems->wide_bw_chansw_ie)) { 615 elem_parse_failed = 616 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 617 break; 618 } 619 elems->wide_bw_chansw_ie = (void *)pos; 620 break; 621 case WLAN_EID_CHANNEL_SWITCH_WRAPPER: 622 if (params->mode < IEEE80211_CONN_MODE_VHT) 623 break; 624 if (params->type == (IEEE80211_FTYPE_MGMT | 625 IEEE80211_STYPE_ACTION)) { 626 elem_parse_failed = 627 IEEE80211_PARSE_ERR_UNEXPECTED_ELEM; 628 break; 629 } 630 /* 631 * This is a bit tricky, but as we only care about 632 * a few elements, parse them out manually. 633 */ 634 subelem = cfg80211_find_elem(WLAN_EID_WIDE_BW_CHANNEL_SWITCH, 635 pos, elen); 636 if (subelem) { 637 if (subelem->datalen >= sizeof(*elems->wide_bw_chansw_ie)) 638 elems->wide_bw_chansw_ie = 639 (void *)subelem->data; 640 else 641 elem_parse_failed = 642 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 643 } 644 645 if (params->mode < IEEE80211_CONN_MODE_EHT) 646 break; 647 648 subelem = cfg80211_find_ext_elem(WLAN_EID_EXT_BANDWIDTH_INDICATION, 649 pos, elen); 650 if (subelem) { 651 const void *edata = subelem->data + 1; 652 u8 edatalen = subelem->datalen - 1; 653 654 if (ieee80211_bandwidth_indication_size_ok(edata, 655 edatalen)) 656 elems->bandwidth_indication = edata; 657 else 658 elem_parse_failed = 659 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 660 } 661 662 subelem = cfg80211_find_ext_elem(WLAN_EID_TX_POWER_ENVELOPE, 663 pos, elen); 664 if (subelem) 665 ieee80211_parse_tpe(&elems->csa_tpe, 666 subelem->data + 1, 667 subelem->datalen - 1); 668 break; 669 case WLAN_EID_COUNTRY: 670 elems->country_elem = pos; 671 elems->country_elem_len = elen; 672 break; 673 case WLAN_EID_PWR_CONSTRAINT: 674 if (elen != 1) { 675 elem_parse_failed = 676 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 677 break; 678 } 679 elems->pwr_constr_elem = pos; 680 break; 681 case WLAN_EID_CISCO_VENDOR_SPECIFIC: 682 /* Lots of different options exist, but we only care 683 * about the Dynamic Transmit Power Control element. 684 * First check for the Cisco OUI, then for the DTPC 685 * tag (0x00). 686 */ 687 if (elen < 4) { 688 elem_parse_failed = 689 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 690 break; 691 } 692 693 if (pos[0] != 0x00 || pos[1] != 0x40 || 694 pos[2] != 0x96 || pos[3] != 0x00) 695 break; 696 697 if (elen != 6) { 698 elem_parse_failed = 699 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 700 break; 701 } 702 703 if (calc_crc) 704 crc = crc32_be(crc, pos - 2, elen + 2); 705 706 elems->cisco_dtpc_elem = pos; 707 break; 708 case WLAN_EID_ADDBA_EXT: 709 if (elen < sizeof(struct ieee80211_addba_ext_ie)) { 710 elem_parse_failed = 711 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 712 break; 713 } 714 elems->addba_ext_ie = (void *)pos; 715 break; 716 case WLAN_EID_TIMEOUT_INTERVAL: 717 if (elen >= sizeof(struct ieee80211_timeout_interval_ie)) 718 elems->timeout_int = (void *)pos; 719 else 720 elem_parse_failed = 721 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 722 break; 723 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 724 if (elen >= sizeof(*elems->max_idle_period_ie)) 725 elems->max_idle_period_ie = (void *)pos; 726 break; 727 case WLAN_EID_RSNX: 728 elems->rsnx = pos; 729 elems->rsnx_len = elen; 730 break; 731 case WLAN_EID_TX_POWER_ENVELOPE: 732 if (params->mode < IEEE80211_CONN_MODE_HE) 733 break; 734 ieee80211_parse_tpe(&elems->tpe, pos, elen); 735 break; 736 case WLAN_EID_EXTENSION: 737 ieee80211_parse_extension_element(calc_crc ? 738 &crc : NULL, 739 elem, elems_parse, 740 params); 741 break; 742 case WLAN_EID_S1G_CAPABILITIES: 743 if (params->mode != IEEE80211_CONN_MODE_S1G) 744 break; 745 if (elen >= sizeof(*elems->s1g_capab)) 746 elems->s1g_capab = (void *)pos; 747 else 748 elem_parse_failed = 749 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 750 break; 751 case WLAN_EID_S1G_OPERATION: 752 if (params->mode != IEEE80211_CONN_MODE_S1G) 753 break; 754 if (elen == sizeof(*elems->s1g_oper)) 755 elems->s1g_oper = (void *)pos; 756 else 757 elem_parse_failed = 758 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 759 break; 760 case WLAN_EID_S1G_BCN_COMPAT: 761 if (params->mode != IEEE80211_CONN_MODE_S1G) 762 break; 763 if (elen == sizeof(*elems->s1g_bcn_compat)) 764 elems->s1g_bcn_compat = (void *)pos; 765 else 766 elem_parse_failed = 767 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 768 break; 769 case WLAN_EID_AID_RESPONSE: 770 if (params->mode != IEEE80211_CONN_MODE_S1G) 771 break; 772 if (elen == sizeof(struct ieee80211_aid_response_ie)) 773 elems->aid_resp = (void *)pos; 774 else 775 elem_parse_failed = 776 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 777 break; 778 default: 779 break; 780 } 781 782 if (elem_parse_failed) 783 elems->parse_error |= elem_parse_failed; 784 else 785 __set_bit(id, seen_elems); 786 } 787 788 if (!for_each_element_completed(elem, params->start, params->len)) 789 elems->parse_error |= IEEE80211_PARSE_ERR_INVALID_END; 790 791 return crc; 792 } 793 794 static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, 795 struct ieee802_11_elems *elems, 796 struct cfg80211_bss *bss, 797 u8 *nontransmitted_profile) 798 { 799 const struct element *elem, *sub; 800 size_t profile_len = 0; 801 802 if (!bss || !bss->transmitted_bss) 803 return profile_len; 804 805 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { 806 if (elem->datalen < 2) 807 continue; 808 if (elem->data[0] < 1 || elem->data[0] > 8) 809 continue; 810 811 for_each_element(sub, elem->data + 1, elem->datalen - 1) { 812 u8 new_bssid[ETH_ALEN]; 813 const u8 *index; 814 815 if (sub->id != 0 || sub->datalen < 4) { 816 /* not a valid BSS profile */ 817 continue; 818 } 819 820 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP || 821 sub->data[1] != 2) { 822 /* The first element of the 823 * Nontransmitted BSSID Profile is not 824 * the Nontransmitted BSSID Capability 825 * element. 826 */ 827 continue; 828 } 829 830 memset(nontransmitted_profile, 0, len); 831 profile_len = cfg80211_merge_profile(start, len, 832 elem, 833 sub, 834 nontransmitted_profile, 835 len); 836 837 /* found a Nontransmitted BSSID Profile */ 838 index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, 839 nontransmitted_profile, 840 profile_len); 841 if (!index || index[1] < 1 || index[2] == 0) { 842 /* Invalid MBSSID Index element */ 843 continue; 844 } 845 846 cfg80211_gen_new_bssid(bss->transmitted_bss->bssid, 847 elem->data[0], 848 index[2], 849 new_bssid); 850 if (ether_addr_equal(new_bssid, bss->bssid)) { 851 elems->bssid_index_len = index[1]; 852 elems->bssid_index = (void *)&index[2]; 853 return profile_len; 854 } 855 } 856 } 857 858 return 0; 859 } 860 861 static void 862 ieee80211_mle_get_sta_prof(struct ieee80211_elems_parse *elems_parse, 863 u8 link_id) 864 { 865 struct ieee802_11_elems *elems = &elems_parse->elems; 866 const struct ieee80211_multi_link_elem *ml = elems->ml_basic; 867 ssize_t ml_len = elems->ml_basic_len; 868 const struct element *sub; 869 870 for_each_mle_subelement(sub, (u8 *)ml, ml_len) { 871 struct ieee80211_mle_per_sta_profile *prof = (void *)sub->data; 872 ssize_t sta_prof_len; 873 u16 control; 874 875 if (sub->id != IEEE80211_MLE_SUBELEM_PER_STA_PROFILE) 876 continue; 877 878 if (!ieee80211_mle_basic_sta_prof_size_ok(sub->data, 879 sub->datalen)) 880 return; 881 882 control = le16_to_cpu(prof->control); 883 884 if (link_id != u16_get_bits(control, 885 IEEE80211_MLE_STA_CONTROL_LINK_ID)) 886 continue; 887 888 if (!(control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE)) 889 return; 890 891 /* the sub element can be fragmented */ 892 sta_prof_len = 893 cfg80211_defragment_element(sub, 894 (u8 *)ml, ml_len, 895 elems_parse->scratch_pos, 896 elems_parse->scratch + 897 elems_parse->scratch_len - 898 elems_parse->scratch_pos, 899 IEEE80211_MLE_SUBELEM_FRAGMENT); 900 901 if (sta_prof_len < 0) 902 return; 903 904 elems->prof = (void *)elems_parse->scratch_pos; 905 elems->sta_prof_len = sta_prof_len; 906 elems_parse->scratch_pos += sta_prof_len; 907 908 return; 909 } 910 } 911 912 static const struct element * 913 ieee80211_prep_mle_link_parse(struct ieee80211_elems_parse *elems_parse, 914 struct ieee80211_elems_parse_params *params, 915 struct ieee80211_elems_parse_params *sub) 916 { 917 struct ieee802_11_elems *elems = &elems_parse->elems; 918 struct ieee80211_mle_per_sta_profile *prof; 919 const struct element *tmp; 920 ssize_t ml_len; 921 const u8 *end; 922 923 if (params->mode < IEEE80211_CONN_MODE_EHT) 924 return NULL; 925 926 for_each_element_extid(tmp, WLAN_EID_EXT_EHT_MULTI_LINK, 927 elems->ie_start, elems->total_len) { 928 const struct ieee80211_multi_link_elem *mle = 929 (void *)tmp->data + 1; 930 931 if (!ieee80211_mle_size_ok(tmp->data + 1, tmp->datalen - 1)) 932 continue; 933 934 if (le16_get_bits(mle->control, IEEE80211_ML_CONTROL_TYPE) != 935 IEEE80211_ML_CONTROL_TYPE_BASIC) 936 continue; 937 938 elems_parse->ml_basic_elem = tmp; 939 break; 940 } 941 942 ml_len = cfg80211_defragment_element(elems_parse->ml_basic_elem, 943 elems->ie_start, 944 elems->total_len, 945 elems_parse->scratch_pos, 946 elems_parse->scratch + 947 elems_parse->scratch_len - 948 elems_parse->scratch_pos, 949 WLAN_EID_FRAGMENT); 950 951 if (ml_len < 0) 952 return NULL; 953 954 elems->ml_basic = (const void *)elems_parse->scratch_pos; 955 elems->ml_basic_len = ml_len; 956 elems_parse->scratch_pos += ml_len; 957 958 if (params->link_id == -1) 959 return NULL; 960 961 ieee80211_mle_get_sta_prof(elems_parse, params->link_id); 962 prof = elems->prof; 963 964 if (!prof) 965 return NULL; 966 967 /* check if we have the 4 bytes for the fixed part in assoc response */ 968 if (elems->sta_prof_len < sizeof(*prof) + prof->sta_info_len - 1 + 4) { 969 elems->prof = NULL; 970 elems->sta_prof_len = 0; 971 return NULL; 972 } 973 974 /* 975 * Skip the capability information and the status code that are expected 976 * as part of the station profile in association response frames. Note 977 * the -1 is because the 'sta_info_len' is accounted to as part of the 978 * per-STA profile, but not part of the 'u8 variable[]' portion. 979 */ 980 sub->start = prof->variable + prof->sta_info_len - 1 + 4; 981 end = (const u8 *)prof + elems->sta_prof_len; 982 sub->len = end - sub->start; 983 984 sub->mode = params->mode; 985 sub->type = params->type; 986 sub->from_ap = params->from_ap; 987 sub->link_id = -1; 988 989 return cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, 990 sub->start, sub->len); 991 } 992 993 static void 994 ieee80211_mle_defrag_reconf(struct ieee80211_elems_parse *elems_parse) 995 { 996 struct ieee802_11_elems *elems = &elems_parse->elems; 997 ssize_t ml_len; 998 999 ml_len = cfg80211_defragment_element(elems_parse->ml_reconf_elem, 1000 elems->ie_start, 1001 elems->total_len, 1002 elems_parse->scratch_pos, 1003 elems_parse->scratch + 1004 elems_parse->scratch_len - 1005 elems_parse->scratch_pos, 1006 WLAN_EID_FRAGMENT); 1007 if (ml_len < 0) 1008 return; 1009 elems->ml_reconf = (void *)elems_parse->scratch_pos; 1010 elems->ml_reconf_len = ml_len; 1011 elems_parse->scratch_pos += ml_len; 1012 } 1013 1014 static void 1015 ieee80211_mle_defrag_epcs(struct ieee80211_elems_parse *elems_parse) 1016 { 1017 struct ieee802_11_elems *elems = &elems_parse->elems; 1018 ssize_t ml_len; 1019 1020 ml_len = cfg80211_defragment_element(elems_parse->ml_epcs_elem, 1021 elems->ie_start, 1022 elems->total_len, 1023 elems_parse->scratch_pos, 1024 elems_parse->scratch + 1025 elems_parse->scratch_len - 1026 elems_parse->scratch_pos, 1027 WLAN_EID_FRAGMENT); 1028 if (ml_len < 0) 1029 return; 1030 elems->ml_epcs = (void *)elems_parse->scratch_pos; 1031 elems->ml_epcs_len = ml_len; 1032 elems_parse->scratch_pos += ml_len; 1033 } 1034 1035 struct ieee802_11_elems * 1036 ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params) 1037 { 1038 struct ieee80211_elems_parse_params sub = {}; 1039 struct ieee80211_elems_parse *elems_parse; 1040 const struct element *non_inherit = NULL; 1041 struct ieee802_11_elems *elems; 1042 size_t scratch_len = 3 * params->len; 1043 bool multi_link_inner = false; 1044 1045 BUILD_BUG_ON(offsetof(typeof(*elems_parse), elems) != 0); 1046 1047 /* cannot parse for both a specific link and non-transmitted BSS */ 1048 if (WARN_ON(params->link_id >= 0 && params->bss)) 1049 return NULL; 1050 1051 elems_parse = kzalloc(struct_size(elems_parse, scratch, scratch_len), 1052 GFP_ATOMIC); 1053 if (!elems_parse) 1054 return NULL; 1055 1056 elems_parse->scratch_len = scratch_len; 1057 elems_parse->scratch_pos = elems_parse->scratch; 1058 1059 elems = &elems_parse->elems; 1060 elems->ie_start = params->start; 1061 elems->total_len = params->len; 1062 1063 /* set all TPE entries to unlimited (but invalid) */ 1064 ieee80211_clear_tpe(&elems->tpe); 1065 ieee80211_clear_tpe(&elems->csa_tpe); 1066 1067 /* 1068 * If we're looking for a non-transmitted BSS then we cannot at 1069 * the same time be looking for a second link as the two can only 1070 * appear in the same frame carrying info for different BSSes. 1071 * 1072 * In any case, we only look for one at a time, as encoded by 1073 * the WARN_ON above. 1074 */ 1075 if (params->bss) { 1076 int nontx_len = 1077 ieee802_11_find_bssid_profile(params->start, 1078 params->len, 1079 elems, params->bss, 1080 elems_parse->scratch_pos); 1081 sub.start = elems_parse->scratch_pos; 1082 sub.mode = params->mode; 1083 sub.len = nontx_len; 1084 sub.type = params->type; 1085 sub.link_id = params->link_id; 1086 1087 /* consume the space used for non-transmitted profile */ 1088 elems_parse->scratch_pos += nontx_len; 1089 1090 non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, 1091 sub.start, nontx_len); 1092 } else { 1093 /* must always parse to get elems_parse->ml_basic_elem */ 1094 non_inherit = ieee80211_prep_mle_link_parse(elems_parse, params, 1095 &sub); 1096 multi_link_inner = true; 1097 } 1098 1099 elems_parse->skip_vendor = 1100 cfg80211_find_elem(WLAN_EID_VENDOR_SPECIFIC, 1101 sub.start, sub.len); 1102 elems->crc = _ieee802_11_parse_elems_full(params, elems_parse, 1103 non_inherit); 1104 1105 /* Override with nontransmitted/per-STA profile if found */ 1106 if (sub.len) { 1107 elems_parse->multi_link_inner = multi_link_inner; 1108 elems_parse->skip_vendor = false; 1109 _ieee802_11_parse_elems_full(&sub, elems_parse, NULL); 1110 } 1111 1112 ieee80211_mle_defrag_reconf(elems_parse); 1113 1114 ieee80211_mle_defrag_epcs(elems_parse); 1115 1116 if (elems->tim && !elems->parse_error) { 1117 const struct ieee80211_tim_ie *tim_ie = elems->tim; 1118 1119 elems->dtim_period = tim_ie->dtim_period; 1120 elems->dtim_count = tim_ie->dtim_count; 1121 } 1122 1123 /* Override DTIM period and count if needed */ 1124 if (elems->bssid_index && 1125 elems->bssid_index_len >= 1126 offsetofend(struct ieee80211_bssid_index, dtim_period)) 1127 elems->dtim_period = elems->bssid_index->dtim_period; 1128 1129 if (elems->bssid_index && 1130 elems->bssid_index_len >= 1131 offsetofend(struct ieee80211_bssid_index, dtim_count)) 1132 elems->dtim_count = elems->bssid_index->dtim_count; 1133 1134 return elems; 1135 } 1136 EXPORT_SYMBOL_IF_KUNIT(ieee802_11_parse_elems_full); 1137 1138 int ieee80211_parse_bitrates(const struct ieee80211_supported_band *sband, 1139 const u8 *srates, int srates_len, u32 *rates) 1140 { 1141 struct ieee80211_rate *br; 1142 int brate, rate, i, j, count = 0; 1143 1144 *rates = 0; 1145 1146 for (i = 0; i < srates_len; i++) { 1147 rate = srates[i] & 0x7f; 1148 1149 for (j = 0; j < sband->n_bitrates; j++) { 1150 br = &sband->bitrates[j]; 1151 1152 brate = DIV_ROUND_UP(br->bitrate, 5); 1153 if (brate == rate) { 1154 *rates |= BIT(j); 1155 count++; 1156 break; 1157 } 1158 } 1159 } 1160 return count; 1161 } 1162