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-2024 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 static void 38 ieee80211_parse_extension_element(u32 *crc, 39 const struct element *elem, 40 struct ieee802_11_elems *elems, 41 struct ieee80211_elems_parse_params *params) 42 { 43 const void *data = elem->data + 1; 44 bool calc_crc = false; 45 u8 len; 46 47 if (!elem->datalen) 48 return; 49 50 len = elem->datalen - 1; 51 52 switch (elem->data[0]) { 53 case WLAN_EID_EXT_HE_MU_EDCA: 54 if (params->mode < IEEE80211_CONN_MODE_HE) 55 break; 56 calc_crc = true; 57 if (len >= sizeof(*elems->mu_edca_param_set)) 58 elems->mu_edca_param_set = data; 59 break; 60 case WLAN_EID_EXT_HE_CAPABILITY: 61 if (params->mode < IEEE80211_CONN_MODE_HE) 62 break; 63 if (ieee80211_he_capa_size_ok(data, len)) { 64 elems->he_cap = data; 65 elems->he_cap_len = len; 66 } 67 break; 68 case WLAN_EID_EXT_HE_OPERATION: 69 if (params->mode < IEEE80211_CONN_MODE_HE) 70 break; 71 calc_crc = true; 72 if (len >= sizeof(*elems->he_operation) && 73 len >= ieee80211_he_oper_size(data) - 1) 74 elems->he_operation = data; 75 break; 76 case WLAN_EID_EXT_UORA: 77 if (params->mode < IEEE80211_CONN_MODE_HE) 78 break; 79 if (len >= 1) 80 elems->uora_element = data; 81 break; 82 case WLAN_EID_EXT_MAX_CHANNEL_SWITCH_TIME: 83 if (len == 3) 84 elems->max_channel_switch_time = data; 85 break; 86 case WLAN_EID_EXT_MULTIPLE_BSSID_CONFIGURATION: 87 if (len >= sizeof(*elems->mbssid_config_ie)) 88 elems->mbssid_config_ie = data; 89 break; 90 case WLAN_EID_EXT_HE_SPR: 91 if (params->mode < IEEE80211_CONN_MODE_HE) 92 break; 93 if (len >= sizeof(*elems->he_spr) && 94 len >= ieee80211_he_spr_size(data)) 95 elems->he_spr = data; 96 break; 97 case WLAN_EID_EXT_HE_6GHZ_CAPA: 98 if (params->mode < IEEE80211_CONN_MODE_HE) 99 break; 100 if (len >= sizeof(*elems->he_6ghz_capa)) 101 elems->he_6ghz_capa = data; 102 break; 103 case WLAN_EID_EXT_EHT_CAPABILITY: 104 if (params->mode < IEEE80211_CONN_MODE_EHT) 105 break; 106 if (ieee80211_eht_capa_size_ok(elems->he_cap, 107 data, len, 108 params->from_ap)) { 109 elems->eht_cap = data; 110 elems->eht_cap_len = len; 111 } 112 break; 113 case WLAN_EID_EXT_EHT_OPERATION: 114 if (params->mode < IEEE80211_CONN_MODE_EHT) 115 break; 116 if (ieee80211_eht_oper_size_ok(data, len)) 117 elems->eht_operation = data; 118 calc_crc = true; 119 break; 120 case WLAN_EID_EXT_EHT_MULTI_LINK: 121 if (params->mode < IEEE80211_CONN_MODE_EHT) 122 break; 123 calc_crc = true; 124 125 if (ieee80211_mle_size_ok(data, len)) { 126 const struct ieee80211_multi_link_elem *mle = 127 (void *)data; 128 129 switch (le16_get_bits(mle->control, 130 IEEE80211_ML_CONTROL_TYPE)) { 131 case IEEE80211_ML_CONTROL_TYPE_BASIC: 132 if (elems->ml_basic) { 133 elems->parse_error |= 134 IEEE80211_PARSE_ERR_DUP_NEST_ML_BASIC; 135 break; 136 } 137 elems->ml_basic_elem = (void *)elem; 138 elems->ml_basic = data; 139 elems->ml_basic_len = len; 140 break; 141 case IEEE80211_ML_CONTROL_TYPE_RECONF: 142 elems->ml_reconf_elem = (void *)elem; 143 elems->ml_reconf = data; 144 elems->ml_reconf_len = len; 145 break; 146 default: 147 break; 148 } 149 } 150 break; 151 case WLAN_EID_EXT_BANDWIDTH_INDICATION: 152 if (params->mode < IEEE80211_CONN_MODE_EHT) 153 break; 154 if (ieee80211_bandwidth_indication_size_ok(data, len)) 155 elems->bandwidth_indication = data; 156 calc_crc = true; 157 break; 158 case WLAN_EID_EXT_TID_TO_LINK_MAPPING: 159 if (params->mode < IEEE80211_CONN_MODE_EHT) 160 break; 161 calc_crc = true; 162 if (ieee80211_tid_to_link_map_size_ok(data, len) && 163 elems->ttlm_num < ARRAY_SIZE(elems->ttlm)) { 164 elems->ttlm[elems->ttlm_num] = (void *)data; 165 elems->ttlm_num++; 166 } 167 break; 168 } 169 170 if (crc && calc_crc) 171 *crc = crc32_be(*crc, (void *)elem, elem->datalen + 2); 172 } 173 174 static u32 175 _ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params, 176 struct ieee802_11_elems *elems, 177 const struct element *check_inherit) 178 { 179 const struct element *elem; 180 bool calc_crc = params->filter != 0; 181 DECLARE_BITMAP(seen_elems, 256); 182 u32 crc = params->crc; 183 184 bitmap_zero(seen_elems, 256); 185 186 for_each_element(elem, params->start, params->len) { 187 const struct element *subelem; 188 u8 elem_parse_failed; 189 u8 id = elem->id; 190 u8 elen = elem->datalen; 191 const u8 *pos = elem->data; 192 193 if (check_inherit && 194 !cfg80211_is_element_inherited(elem, 195 check_inherit)) 196 continue; 197 198 switch (id) { 199 case WLAN_EID_SSID: 200 case WLAN_EID_SUPP_RATES: 201 case WLAN_EID_FH_PARAMS: 202 case WLAN_EID_DS_PARAMS: 203 case WLAN_EID_CF_PARAMS: 204 case WLAN_EID_TIM: 205 case WLAN_EID_IBSS_PARAMS: 206 case WLAN_EID_CHALLENGE: 207 case WLAN_EID_RSN: 208 case WLAN_EID_ERP_INFO: 209 case WLAN_EID_EXT_SUPP_RATES: 210 case WLAN_EID_HT_CAPABILITY: 211 case WLAN_EID_HT_OPERATION: 212 case WLAN_EID_VHT_CAPABILITY: 213 case WLAN_EID_VHT_OPERATION: 214 case WLAN_EID_MESH_ID: 215 case WLAN_EID_MESH_CONFIG: 216 case WLAN_EID_PEER_MGMT: 217 case WLAN_EID_PREQ: 218 case WLAN_EID_PREP: 219 case WLAN_EID_PERR: 220 case WLAN_EID_RANN: 221 case WLAN_EID_CHANNEL_SWITCH: 222 case WLAN_EID_EXT_CHANSWITCH_ANN: 223 case WLAN_EID_COUNTRY: 224 case WLAN_EID_PWR_CONSTRAINT: 225 case WLAN_EID_TIMEOUT_INTERVAL: 226 case WLAN_EID_SECONDARY_CHANNEL_OFFSET: 227 case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: 228 case WLAN_EID_CHAN_SWITCH_PARAM: 229 case WLAN_EID_EXT_CAPABILITY: 230 case WLAN_EID_CHAN_SWITCH_TIMING: 231 case WLAN_EID_LINK_ID: 232 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 233 case WLAN_EID_RSNX: 234 case WLAN_EID_S1G_BCN_COMPAT: 235 case WLAN_EID_S1G_CAPABILITIES: 236 case WLAN_EID_S1G_OPERATION: 237 case WLAN_EID_AID_RESPONSE: 238 case WLAN_EID_S1G_SHORT_BCN_INTERVAL: 239 /* 240 * not listing WLAN_EID_CHANNEL_SWITCH_WRAPPER -- it seems possible 241 * that if the content gets bigger it might be needed more than once 242 */ 243 if (test_bit(id, seen_elems)) { 244 elems->parse_error |= 245 IEEE80211_PARSE_ERR_DUP_ELEM; 246 continue; 247 } 248 break; 249 } 250 251 if (calc_crc && id < 64 && (params->filter & (1ULL << id))) 252 crc = crc32_be(crc, pos - 2, elen + 2); 253 254 elem_parse_failed = 0; 255 256 switch (id) { 257 case WLAN_EID_LINK_ID: 258 if (elen + 2 < sizeof(struct ieee80211_tdls_lnkie)) { 259 elem_parse_failed = 260 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 261 break; 262 } 263 elems->lnk_id = (void *)(pos - 2); 264 break; 265 case WLAN_EID_CHAN_SWITCH_TIMING: 266 if (elen < sizeof(struct ieee80211_ch_switch_timing)) { 267 elem_parse_failed = 268 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 269 break; 270 } 271 elems->ch_sw_timing = (void *)pos; 272 break; 273 case WLAN_EID_EXT_CAPABILITY: 274 elems->ext_capab = pos; 275 elems->ext_capab_len = elen; 276 break; 277 case WLAN_EID_SSID: 278 elems->ssid = pos; 279 elems->ssid_len = elen; 280 break; 281 case WLAN_EID_SUPP_RATES: 282 elems->supp_rates = pos; 283 elems->supp_rates_len = elen; 284 break; 285 case WLAN_EID_DS_PARAMS: 286 if (elen >= 1) 287 elems->ds_params = pos; 288 else 289 elem_parse_failed = 290 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 291 break; 292 case WLAN_EID_TIM: 293 if (elen >= sizeof(struct ieee80211_tim_ie)) { 294 elems->tim = (void *)pos; 295 elems->tim_len = elen; 296 } else 297 elem_parse_failed = 298 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 299 break; 300 case WLAN_EID_VENDOR_SPECIFIC: 301 if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 && 302 pos[2] == 0xf2) { 303 /* Microsoft OUI (00:50:F2) */ 304 305 if (calc_crc) 306 crc = crc32_be(crc, pos - 2, elen + 2); 307 308 if (elen >= 5 && pos[3] == 2) { 309 /* OUI Type 2 - WMM IE */ 310 if (pos[4] == 0) { 311 elems->wmm_info = pos; 312 elems->wmm_info_len = elen; 313 } else if (pos[4] == 1) { 314 elems->wmm_param = pos; 315 elems->wmm_param_len = elen; 316 } 317 } 318 } 319 break; 320 case WLAN_EID_RSN: 321 elems->rsn = pos; 322 elems->rsn_len = elen; 323 break; 324 case WLAN_EID_ERP_INFO: 325 if (elen >= 1) 326 elems->erp_info = pos; 327 else 328 elem_parse_failed = 329 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 330 break; 331 case WLAN_EID_EXT_SUPP_RATES: 332 elems->ext_supp_rates = pos; 333 elems->ext_supp_rates_len = elen; 334 break; 335 case WLAN_EID_HT_CAPABILITY: 336 if (params->mode < IEEE80211_CONN_MODE_HT) 337 break; 338 if (elen >= sizeof(struct ieee80211_ht_cap)) 339 elems->ht_cap_elem = (void *)pos; 340 else 341 elem_parse_failed = 342 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 343 break; 344 case WLAN_EID_HT_OPERATION: 345 if (params->mode < IEEE80211_CONN_MODE_HT) 346 break; 347 if (elen >= sizeof(struct ieee80211_ht_operation)) 348 elems->ht_operation = (void *)pos; 349 else 350 elem_parse_failed = 351 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 352 break; 353 case WLAN_EID_VHT_CAPABILITY: 354 if (params->mode < IEEE80211_CONN_MODE_VHT) 355 break; 356 if (elen >= sizeof(struct ieee80211_vht_cap)) 357 elems->vht_cap_elem = (void *)pos; 358 else 359 elem_parse_failed = 360 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 361 break; 362 case WLAN_EID_VHT_OPERATION: 363 if (params->mode < IEEE80211_CONN_MODE_VHT) 364 break; 365 if (elen >= sizeof(struct ieee80211_vht_operation)) { 366 elems->vht_operation = (void *)pos; 367 if (calc_crc) 368 crc = crc32_be(crc, pos - 2, elen + 2); 369 break; 370 } 371 elem_parse_failed = 372 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 373 break; 374 case WLAN_EID_OPMODE_NOTIF: 375 if (params->mode < IEEE80211_CONN_MODE_VHT) 376 break; 377 if (elen > 0) { 378 elems->opmode_notif = pos; 379 if (calc_crc) 380 crc = crc32_be(crc, pos - 2, elen + 2); 381 break; 382 } 383 elem_parse_failed = 384 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 385 break; 386 case WLAN_EID_MESH_ID: 387 elems->mesh_id = pos; 388 elems->mesh_id_len = elen; 389 break; 390 case WLAN_EID_MESH_CONFIG: 391 if (elen >= sizeof(struct ieee80211_meshconf_ie)) 392 elems->mesh_config = (void *)pos; 393 else 394 elem_parse_failed = 395 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 396 break; 397 case WLAN_EID_PEER_MGMT: 398 elems->peering = pos; 399 elems->peering_len = elen; 400 break; 401 case WLAN_EID_MESH_AWAKE_WINDOW: 402 if (elen >= 2) 403 elems->awake_window = (void *)pos; 404 break; 405 case WLAN_EID_PREQ: 406 elems->preq = pos; 407 elems->preq_len = elen; 408 break; 409 case WLAN_EID_PREP: 410 elems->prep = pos; 411 elems->prep_len = elen; 412 break; 413 case WLAN_EID_PERR: 414 elems->perr = pos; 415 elems->perr_len = elen; 416 break; 417 case WLAN_EID_RANN: 418 if (elen >= sizeof(struct ieee80211_rann_ie)) 419 elems->rann = (void *)pos; 420 else 421 elem_parse_failed = 422 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 423 break; 424 case WLAN_EID_CHANNEL_SWITCH: 425 if (elen != sizeof(struct ieee80211_channel_sw_ie)) { 426 elem_parse_failed = 427 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 428 break; 429 } 430 elems->ch_switch_ie = (void *)pos; 431 break; 432 case WLAN_EID_EXT_CHANSWITCH_ANN: 433 if (elen != sizeof(struct ieee80211_ext_chansw_ie)) { 434 elem_parse_failed = 435 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 436 break; 437 } 438 elems->ext_chansw_ie = (void *)pos; 439 break; 440 case WLAN_EID_SECONDARY_CHANNEL_OFFSET: 441 if (params->mode < IEEE80211_CONN_MODE_HT) 442 break; 443 if (elen != sizeof(struct ieee80211_sec_chan_offs_ie)) { 444 elem_parse_failed = 445 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 446 break; 447 } 448 elems->sec_chan_offs = (void *)pos; 449 break; 450 case WLAN_EID_CHAN_SWITCH_PARAM: 451 if (elen < 452 sizeof(*elems->mesh_chansw_params_ie)) { 453 elem_parse_failed = 454 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 455 break; 456 } 457 elems->mesh_chansw_params_ie = (void *)pos; 458 break; 459 case WLAN_EID_WIDE_BW_CHANNEL_SWITCH: 460 if (params->mode < IEEE80211_CONN_MODE_VHT) 461 break; 462 463 if (!params->action) { 464 elem_parse_failed = 465 IEEE80211_PARSE_ERR_UNEXPECTED_ELEM; 466 break; 467 } 468 469 if (elen < sizeof(*elems->wide_bw_chansw_ie)) { 470 elem_parse_failed = 471 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 472 break; 473 } 474 elems->wide_bw_chansw_ie = (void *)pos; 475 break; 476 case WLAN_EID_CHANNEL_SWITCH_WRAPPER: 477 if (params->mode < IEEE80211_CONN_MODE_VHT) 478 break; 479 if (params->action) { 480 elem_parse_failed = 481 IEEE80211_PARSE_ERR_UNEXPECTED_ELEM; 482 break; 483 } 484 /* 485 * This is a bit tricky, but as we only care about 486 * a few elements, parse them out manually. 487 */ 488 subelem = cfg80211_find_elem(WLAN_EID_WIDE_BW_CHANNEL_SWITCH, 489 pos, elen); 490 if (subelem) { 491 if (subelem->datalen >= sizeof(*elems->wide_bw_chansw_ie)) 492 elems->wide_bw_chansw_ie = 493 (void *)subelem->data; 494 else 495 elem_parse_failed = 496 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 497 } 498 499 if (params->mode < IEEE80211_CONN_MODE_EHT) 500 break; 501 502 subelem = cfg80211_find_ext_elem(WLAN_EID_EXT_BANDWIDTH_INDICATION, 503 pos, elen); 504 if (subelem) { 505 const void *edata = subelem->data + 1; 506 u8 edatalen = subelem->datalen - 1; 507 508 if (ieee80211_bandwidth_indication_size_ok(edata, 509 edatalen)) 510 elems->bandwidth_indication = edata; 511 else 512 elem_parse_failed = 513 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 514 } 515 break; 516 case WLAN_EID_COUNTRY: 517 elems->country_elem = pos; 518 elems->country_elem_len = elen; 519 break; 520 case WLAN_EID_PWR_CONSTRAINT: 521 if (elen != 1) { 522 elem_parse_failed = 523 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 524 break; 525 } 526 elems->pwr_constr_elem = pos; 527 break; 528 case WLAN_EID_CISCO_VENDOR_SPECIFIC: 529 /* Lots of different options exist, but we only care 530 * about the Dynamic Transmit Power Control element. 531 * First check for the Cisco OUI, then for the DTPC 532 * tag (0x00). 533 */ 534 if (elen < 4) { 535 elem_parse_failed = 536 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 537 break; 538 } 539 540 if (pos[0] != 0x00 || pos[1] != 0x40 || 541 pos[2] != 0x96 || pos[3] != 0x00) 542 break; 543 544 if (elen != 6) { 545 elem_parse_failed = 546 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 547 break; 548 } 549 550 if (calc_crc) 551 crc = crc32_be(crc, pos - 2, elen + 2); 552 553 elems->cisco_dtpc_elem = pos; 554 break; 555 case WLAN_EID_ADDBA_EXT: 556 if (elen < sizeof(struct ieee80211_addba_ext_ie)) { 557 elem_parse_failed = 558 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 559 break; 560 } 561 elems->addba_ext_ie = (void *)pos; 562 break; 563 case WLAN_EID_TIMEOUT_INTERVAL: 564 if (elen >= sizeof(struct ieee80211_timeout_interval_ie)) 565 elems->timeout_int = (void *)pos; 566 else 567 elem_parse_failed = 568 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 569 break; 570 case WLAN_EID_BSS_MAX_IDLE_PERIOD: 571 if (elen >= sizeof(*elems->max_idle_period_ie)) 572 elems->max_idle_period_ie = (void *)pos; 573 break; 574 case WLAN_EID_RSNX: 575 elems->rsnx = pos; 576 elems->rsnx_len = elen; 577 break; 578 case WLAN_EID_TX_POWER_ENVELOPE: 579 if (elen < 1 || 580 elen > sizeof(struct ieee80211_tx_pwr_env)) 581 break; 582 583 if (elems->tx_pwr_env_num >= ARRAY_SIZE(elems->tx_pwr_env)) 584 break; 585 586 elems->tx_pwr_env[elems->tx_pwr_env_num] = (void *)pos; 587 elems->tx_pwr_env_len[elems->tx_pwr_env_num] = elen; 588 elems->tx_pwr_env_num++; 589 break; 590 case WLAN_EID_EXTENSION: 591 ieee80211_parse_extension_element(calc_crc ? 592 &crc : NULL, 593 elem, elems, params); 594 break; 595 case WLAN_EID_S1G_CAPABILITIES: 596 if (params->mode != IEEE80211_CONN_MODE_S1G) 597 break; 598 if (elen >= sizeof(*elems->s1g_capab)) 599 elems->s1g_capab = (void *)pos; 600 else 601 elem_parse_failed = 602 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 603 break; 604 case WLAN_EID_S1G_OPERATION: 605 if (params->mode != IEEE80211_CONN_MODE_S1G) 606 break; 607 if (elen == sizeof(*elems->s1g_oper)) 608 elems->s1g_oper = (void *)pos; 609 else 610 elem_parse_failed = 611 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 612 break; 613 case WLAN_EID_S1G_BCN_COMPAT: 614 if (params->mode != IEEE80211_CONN_MODE_S1G) 615 break; 616 if (elen == sizeof(*elems->s1g_bcn_compat)) 617 elems->s1g_bcn_compat = (void *)pos; 618 else 619 elem_parse_failed = 620 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 621 break; 622 case WLAN_EID_AID_RESPONSE: 623 if (params->mode != IEEE80211_CONN_MODE_S1G) 624 break; 625 if (elen == sizeof(struct ieee80211_aid_response_ie)) 626 elems->aid_resp = (void *)pos; 627 else 628 elem_parse_failed = 629 IEEE80211_PARSE_ERR_BAD_ELEM_SIZE; 630 break; 631 default: 632 break; 633 } 634 635 if (elem_parse_failed) 636 elems->parse_error |= elem_parse_failed; 637 else 638 __set_bit(id, seen_elems); 639 } 640 641 if (!for_each_element_completed(elem, params->start, params->len)) 642 elems->parse_error |= IEEE80211_PARSE_ERR_INVALID_END; 643 644 return crc; 645 } 646 647 static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len, 648 struct ieee802_11_elems *elems, 649 struct cfg80211_bss *bss, 650 u8 *nontransmitted_profile) 651 { 652 const struct element *elem, *sub; 653 size_t profile_len = 0; 654 bool found = false; 655 656 if (!bss || !bss->transmitted_bss) 657 return profile_len; 658 659 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) { 660 if (elem->datalen < 2) 661 continue; 662 if (elem->data[0] < 1 || elem->data[0] > 8) 663 continue; 664 665 for_each_element(sub, elem->data + 1, elem->datalen - 1) { 666 u8 new_bssid[ETH_ALEN]; 667 const u8 *index; 668 669 if (sub->id != 0 || sub->datalen < 4) { 670 /* not a valid BSS profile */ 671 continue; 672 } 673 674 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP || 675 sub->data[1] != 2) { 676 /* The first element of the 677 * Nontransmitted BSSID Profile is not 678 * the Nontransmitted BSSID Capability 679 * element. 680 */ 681 continue; 682 } 683 684 memset(nontransmitted_profile, 0, len); 685 profile_len = cfg80211_merge_profile(start, len, 686 elem, 687 sub, 688 nontransmitted_profile, 689 len); 690 691 /* found a Nontransmitted BSSID Profile */ 692 index = cfg80211_find_ie(WLAN_EID_MULTI_BSSID_IDX, 693 nontransmitted_profile, 694 profile_len); 695 if (!index || index[1] < 1 || index[2] == 0) { 696 /* Invalid MBSSID Index element */ 697 continue; 698 } 699 700 cfg80211_gen_new_bssid(bss->transmitted_bss->bssid, 701 elem->data[0], 702 index[2], 703 new_bssid); 704 if (ether_addr_equal(new_bssid, bss->bssid)) { 705 found = true; 706 elems->bssid_index_len = index[1]; 707 elems->bssid_index = (void *)&index[2]; 708 break; 709 } 710 } 711 } 712 713 return found ? profile_len : 0; 714 } 715 716 static void ieee80211_mle_get_sta_prof(struct ieee802_11_elems *elems, 717 u8 link_id) 718 { 719 const struct ieee80211_multi_link_elem *ml = elems->ml_basic; 720 ssize_t ml_len = elems->ml_basic_len; 721 const struct element *sub; 722 723 if (!ml || !ml_len) 724 return; 725 726 if (le16_get_bits(ml->control, IEEE80211_ML_CONTROL_TYPE) != 727 IEEE80211_ML_CONTROL_TYPE_BASIC) 728 return; 729 730 for_each_mle_subelement(sub, (u8 *)ml, ml_len) { 731 struct ieee80211_mle_per_sta_profile *prof = (void *)sub->data; 732 ssize_t sta_prof_len; 733 u16 control; 734 735 if (sub->id != IEEE80211_MLE_SUBELEM_PER_STA_PROFILE) 736 continue; 737 738 if (!ieee80211_mle_basic_sta_prof_size_ok(sub->data, 739 sub->datalen)) 740 return; 741 742 control = le16_to_cpu(prof->control); 743 744 if (link_id != u16_get_bits(control, 745 IEEE80211_MLE_STA_CONTROL_LINK_ID)) 746 continue; 747 748 if (!(control & IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE)) 749 return; 750 751 /* the sub element can be fragmented */ 752 sta_prof_len = 753 cfg80211_defragment_element(sub, 754 (u8 *)ml, ml_len, 755 elems->scratch_pos, 756 elems->scratch + 757 elems->scratch_len - 758 elems->scratch_pos, 759 IEEE80211_MLE_SUBELEM_FRAGMENT); 760 761 if (sta_prof_len < 0) 762 return; 763 764 elems->prof = (void *)elems->scratch_pos; 765 elems->sta_prof_len = sta_prof_len; 766 elems->scratch_pos += sta_prof_len; 767 768 return; 769 } 770 } 771 772 static void ieee80211_mle_parse_link(struct ieee802_11_elems *elems, 773 struct ieee80211_elems_parse_params *params) 774 { 775 struct ieee80211_mle_per_sta_profile *prof; 776 struct ieee80211_elems_parse_params sub = { 777 .mode = params->mode, 778 .action = params->action, 779 .from_ap = params->from_ap, 780 .link_id = -1, 781 }; 782 ssize_t ml_len = elems->ml_basic_len; 783 const struct element *non_inherit = NULL; 784 const u8 *end; 785 786 if (params->link_id == -1) 787 return; 788 789 ml_len = cfg80211_defragment_element(elems->ml_basic_elem, 790 elems->ie_start, 791 elems->total_len, 792 elems->scratch_pos, 793 elems->scratch + 794 elems->scratch_len - 795 elems->scratch_pos, 796 WLAN_EID_FRAGMENT); 797 798 if (ml_len < 0) 799 return; 800 801 elems->ml_basic = (const void *)elems->scratch_pos; 802 elems->ml_basic_len = ml_len; 803 804 ieee80211_mle_get_sta_prof(elems, params->link_id); 805 prof = elems->prof; 806 807 if (!prof) 808 return; 809 810 /* check if we have the 4 bytes for the fixed part in assoc response */ 811 if (elems->sta_prof_len < sizeof(*prof) + prof->sta_info_len - 1 + 4) { 812 elems->prof = NULL; 813 elems->sta_prof_len = 0; 814 return; 815 } 816 817 /* 818 * Skip the capability information and the status code that are expected 819 * as part of the station profile in association response frames. Note 820 * the -1 is because the 'sta_info_len' is accounted to as part of the 821 * per-STA profile, but not part of the 'u8 variable[]' portion. 822 */ 823 sub.start = prof->variable + prof->sta_info_len - 1 + 4; 824 end = (const u8 *)prof + elems->sta_prof_len; 825 sub.len = end - sub.start; 826 827 non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, 828 sub.start, sub.len); 829 _ieee802_11_parse_elems_full(&sub, elems, non_inherit); 830 } 831 832 struct ieee802_11_elems * 833 ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params) 834 { 835 struct ieee802_11_elems *elems; 836 const struct element *non_inherit = NULL; 837 u8 *nontransmitted_profile; 838 int nontransmitted_profile_len = 0; 839 size_t scratch_len = 3 * params->len; 840 841 elems = kzalloc(struct_size(elems, scratch, scratch_len), GFP_ATOMIC); 842 if (!elems) 843 return NULL; 844 elems->ie_start = params->start; 845 elems->total_len = params->len; 846 elems->scratch_len = scratch_len; 847 elems->scratch_pos = elems->scratch; 848 849 nontransmitted_profile = elems->scratch_pos; 850 nontransmitted_profile_len = 851 ieee802_11_find_bssid_profile(params->start, params->len, 852 elems, params->bss, 853 nontransmitted_profile); 854 elems->scratch_pos += nontransmitted_profile_len; 855 elems->scratch_len -= nontransmitted_profile_len; 856 non_inherit = cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE, 857 nontransmitted_profile, 858 nontransmitted_profile_len); 859 860 elems->crc = _ieee802_11_parse_elems_full(params, elems, non_inherit); 861 862 /* Override with nontransmitted profile, if found */ 863 if (nontransmitted_profile_len) { 864 struct ieee80211_elems_parse_params sub = { 865 .mode = params->mode, 866 .start = nontransmitted_profile, 867 .len = nontransmitted_profile_len, 868 .action = params->action, 869 .link_id = params->link_id, 870 }; 871 872 _ieee802_11_parse_elems_full(&sub, elems, NULL); 873 } 874 875 ieee80211_mle_parse_link(elems, params); 876 877 if (elems->tim && !elems->parse_error) { 878 const struct ieee80211_tim_ie *tim_ie = elems->tim; 879 880 elems->dtim_period = tim_ie->dtim_period; 881 elems->dtim_count = tim_ie->dtim_count; 882 } 883 884 /* Override DTIM period and count if needed */ 885 if (elems->bssid_index && 886 elems->bssid_index_len >= 887 offsetofend(struct ieee80211_bssid_index, dtim_period)) 888 elems->dtim_period = elems->bssid_index->dtim_period; 889 890 if (elems->bssid_index && 891 elems->bssid_index_len >= 892 offsetofend(struct ieee80211_bssid_index, dtim_count)) 893 elems->dtim_count = elems->bssid_index->dtim_count; 894 895 return elems; 896 } 897 EXPORT_SYMBOL_IF_KUNIT(ieee802_11_parse_elems_full); 898 899 int ieee80211_parse_bitrates(enum nl80211_chan_width width, 900 const struct ieee80211_supported_band *sband, 901 const u8 *srates, int srates_len, u32 *rates) 902 { 903 u32 rate_flags = ieee80211_chanwidth_rate_flags(width); 904 struct ieee80211_rate *br; 905 int brate, rate, i, j, count = 0; 906 907 *rates = 0; 908 909 for (i = 0; i < srates_len; i++) { 910 rate = srates[i] & 0x7f; 911 912 for (j = 0; j < sband->n_bitrates; j++) { 913 br = &sband->bitrates[j]; 914 if ((rate_flags & br->flags) != rate_flags) 915 continue; 916 917 brate = DIV_ROUND_UP(br->bitrate, 5); 918 if (brate == rate) { 919 *rates |= BIT(j); 920 count++; 921 break; 922 } 923 } 924 } 925 return count; 926 } 927