summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2019-02-07 16:36:33 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-02-08 07:51:50 -0500
commit1c8745f3ec6f46f5fa99dbcdf92381144ae1b37f (patch)
tree5b5afc6da8efa240c4fe0cc0c72b16ce1bcbdb41 /net/wireless
parent0b8fb8235be8be99a197e8d948fc0a2df8dc261a (diff)
cfg80211: use for_each_element() for multi-bssid parsing
Use the new for_each_element() helper here, we cannot use for_each_subelement() since we have a fixed 1 byte before the subelements start. While at it, also fix le16_to_cpup() to be get_unaligned_le16() since we don't know anything about alignment. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/scan.c47
1 files changed, 15 insertions, 32 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 531c2e56413f..54feb7741c26 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1377,9 +1377,9 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
1377 struct cfg80211_bss *trans_bss, 1377 struct cfg80211_bss *trans_bss,
1378 gfp_t gfp) 1378 gfp_t gfp)
1379{ 1379{
1380 const u8 *pos, *subelement, *mbssid_end_pos; 1380 const u8 *mbssid_index_ie;
1381 const u8 *tmp, *mbssid_index_ie; 1381 const struct element *elem, *sub;
1382 size_t subie_len, new_ie_len; 1382 size_t new_ie_len;
1383 u8 new_bssid[ETH_ALEN]; 1383 u8 new_bssid[ETH_ALEN];
1384 u8 *new_ie; 1384 u8 *new_ie;
1385 u16 capability; 1385 u16 capability;
@@ -1390,34 +1390,21 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
1390 if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) 1390 if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
1391 return; 1391 return;
1392 1392
1393 pos = ie;
1394
1395 new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp); 1393 new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
1396 if (!new_ie) 1394 if (!new_ie)
1397 return; 1395 return;
1398 1396
1399 while (pos < ie + ielen + 2) { 1397 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
1400 tmp = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, pos, 1398 if (elem->datalen < 4)
1401 ielen - (pos - ie)); 1399 continue;
1402 if (!tmp) 1400 for_each_element(sub, elem->data + 1, elem->datalen - 1) {
1403 break; 1401 if (sub->id != 0 || sub->datalen < 4) {
1404
1405 mbssid_end_pos = tmp + tmp[1] + 2;
1406 /* Skip Element ID, Len, MaxBSSID Indicator */
1407 if (tmp[1] < 4)
1408 break;
1409 for (subelement = tmp + 3; subelement < mbssid_end_pos - 1;
1410 subelement += 2 + subelement[1]) {
1411 subie_len = subelement[1];
1412 if (mbssid_end_pos - subelement < 2 + subie_len)
1413 break;
1414 if (subelement[0] != 0 || subelement[1] < 4) {
1415 /* not a valid BSS profile */ 1402 /* not a valid BSS profile */
1416 continue; 1403 continue;
1417 } 1404 }
1418 1405
1419 if (subelement[2] != WLAN_EID_NON_TX_BSSID_CAP || 1406 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
1420 subelement[3] != 2) { 1407 sub->data[1] != 2) {
1421 /* The first element within the Nontransmitted 1408 /* The first element within the Nontransmitted
1422 * BSSID Profile is not the Nontransmitted 1409 * BSSID Profile is not the Nontransmitted
1423 * BSSID Capability element. 1410 * BSSID Capability element.
@@ -1428,26 +1415,24 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
1428 /* found a Nontransmitted BSSID Profile */ 1415 /* found a Nontransmitted BSSID Profile */
1429 mbssid_index_ie = cfg80211_find_ie 1416 mbssid_index_ie = cfg80211_find_ie
1430 (WLAN_EID_MULTI_BSSID_IDX, 1417 (WLAN_EID_MULTI_BSSID_IDX,
1431 subelement + 2, subie_len); 1418 sub->data, sub->datalen);
1432 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || 1419 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
1433 mbssid_index_ie[2] == 0) { 1420 mbssid_index_ie[2] == 0) {
1434 /* No valid Multiple BSSID-Index element */ 1421 /* No valid Multiple BSSID-Index element */
1435 continue; 1422 continue;
1436 } 1423 }
1437 1424
1438 cfg80211_gen_new_bssid(bssid, tmp[2], 1425 cfg80211_gen_new_bssid(bssid, elem->data[0],
1439 mbssid_index_ie[2], 1426 mbssid_index_ie[2],
1440 new_bssid); 1427 new_bssid);
1441 memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); 1428 memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
1442 new_ie_len = cfg80211_gen_new_ie(ie, ielen, 1429 new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data,
1443 subelement + 2, 1430 sub->datalen, new_ie,
1444 subie_len, new_ie,
1445 gfp); 1431 gfp);
1446 if (!new_ie_len) 1432 if (!new_ie_len)
1447 continue; 1433 continue;
1448 1434
1449 capability = le16_to_cpup((const __le16 *) 1435 capability = get_unaligned_le16(sub->data + 2);
1450 &subelement[4]);
1451 bss = cfg80211_inform_single_bss_data(wiphy, data, 1436 bss = cfg80211_inform_single_bss_data(wiphy, data,
1452 ftype, 1437 ftype,
1453 new_bssid, tsf, 1438 new_bssid, tsf,
@@ -1460,8 +1445,6 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
1460 break; 1445 break;
1461 cfg80211_put_bss(wiphy, bss); 1446 cfg80211_put_bss(wiphy, bss);
1462 } 1447 }
1463
1464 pos = mbssid_end_pos;
1465 } 1448 }
1466 1449
1467 kfree(new_ie); 1450 kfree(new_ie);