Skip to content

Commit 1c8745f

Browse files
committed
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 <[email protected]>
1 parent 0b8fb82 commit 1c8745f

File tree

1 file changed

+15
-32
lines changed

1 file changed

+15
-32
lines changed

net/wireless/scan.c

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,9 +1377,9 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
13771377
struct cfg80211_bss *trans_bss,
13781378
gfp_t gfp)
13791379
{
1380-
const u8 *pos, *subelement, *mbssid_end_pos;
1381-
const u8 *tmp, *mbssid_index_ie;
1382-
size_t subie_len, new_ie_len;
1380+
const u8 *mbssid_index_ie;
1381+
const struct element *elem, *sub;
1382+
size_t new_ie_len;
13831383
u8 new_bssid[ETH_ALEN];
13841384
u8 *new_ie;
13851385
u16 capability;
@@ -1390,34 +1390,21 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
13901390
if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
13911391
return;
13921392

1393-
pos = ie;
1394-
13951393
new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp);
13961394
if (!new_ie)
13971395
return;
13981396

1399-
while (pos < ie + ielen + 2) {
1400-
tmp = cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, pos,
1401-
ielen - (pos - ie));
1402-
if (!tmp)
1403-
break;
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) {
1397+
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
1398+
if (elem->datalen < 4)
1399+
continue;
1400+
for_each_element(sub, elem->data + 1, elem->datalen - 1) {
1401+
if (sub->id != 0 || sub->datalen < 4) {
14151402
/* not a valid BSS profile */
14161403
continue;
14171404
}
14181405

1419-
if (subelement[2] != WLAN_EID_NON_TX_BSSID_CAP ||
1420-
subelement[3] != 2) {
1406+
if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP ||
1407+
sub->data[1] != 2) {
14211408
/* The first element within the Nontransmitted
14221409
* BSSID Profile is not the Nontransmitted
14231410
* BSSID Capability element.
@@ -1428,26 +1415,24 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
14281415
/* found a Nontransmitted BSSID Profile */
14291416
mbssid_index_ie = cfg80211_find_ie
14301417
(WLAN_EID_MULTI_BSSID_IDX,
1431-
subelement + 2, subie_len);
1418+
sub->data, sub->datalen);
14321419
if (!mbssid_index_ie || mbssid_index_ie[1] < 1 ||
14331420
mbssid_index_ie[2] == 0) {
14341421
/* No valid Multiple BSSID-Index element */
14351422
continue;
14361423
}
14371424

1438-
cfg80211_gen_new_bssid(bssid, tmp[2],
1425+
cfg80211_gen_new_bssid(bssid, elem->data[0],
14391426
mbssid_index_ie[2],
14401427
new_bssid);
14411428
memset(new_ie, 0, IEEE80211_MAX_DATA_LEN);
1442-
new_ie_len = cfg80211_gen_new_ie(ie, ielen,
1443-
subelement + 2,
1444-
subie_len, new_ie,
1429+
new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data,
1430+
sub->datalen, new_ie,
14451431
gfp);
14461432
if (!new_ie_len)
14471433
continue;
14481434

1449-
capability = le16_to_cpup((const __le16 *)
1450-
&subelement[4]);
1435+
capability = get_unaligned_le16(sub->data + 2);
14511436
bss = cfg80211_inform_single_bss_data(wiphy, data,
14521437
ftype,
14531438
new_bssid, tsf,
@@ -1460,8 +1445,6 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy,
14601445
break;
14611446
cfg80211_put_bss(wiphy, bss);
14621447
}
1463-
1464-
pos = mbssid_end_pos;
14651448
}
14661449

14671450
kfree(new_ie);

0 commit comments

Comments
 (0)