Message ID | 20190315153907.16192-10-luca@coelho.fi (mailing list archive) |
---|---|
State | Accepted |
Delegated to: | Johannes Berg |
Headers | show |
Series | cfg80211/mac80211 patches from our internal tree 2019-03-15 | expand |
Hi Luca, Thank you for the patch! Perhaps something to improve: url: https://github.com/0day-ci/linux/commits/Luca-Coelho/mac80211-Increase-MAX_MSG_LEN/20190316-083719 base: https://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git master smatch warnings: net/wireless/scan.c:1610 cfg80211_parse_mbssid_data() warn: should '1 << (mbssid_index_ie[2])' be a 64 bit type? # https://github.com/0day-ci/linux/commit/e28e850d09f80732c1e9c04e0079c4e40f23ef7d git remote add linux-review https://github.com/0day-ci/linux git remote update linux-review git checkout e28e850d09f80732c1e9c04e0079c4e40f23ef7d vim +1610 net/wireless/scan.c e28e850d Sara Sharon 2019-03-15 1530 0b8fb823 Peng Xu 2019-01-21 1531 static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, 0b8fb823 Peng Xu 2019-01-21 1532 struct cfg80211_inform_bss *data, 0b8fb823 Peng Xu 2019-01-21 1533 enum cfg80211_bss_frame_type ftype, 0b8fb823 Peng Xu 2019-01-21 1534 const u8 *bssid, u64 tsf, 0b8fb823 Peng Xu 2019-01-21 1535 u16 beacon_interval, const u8 *ie, 0b8fb823 Peng Xu 2019-01-21 1536 size_t ielen, 0cd01efb Sara Sharon 2019-01-22 1537 struct cfg80211_non_tx_bss *non_tx_data, 0b8fb823 Peng Xu 2019-01-21 1538 gfp_t gfp) 0b8fb823 Peng Xu 2019-01-21 1539 { 1c8745f3 Johannes Berg 2019-02-07 1540 const u8 *mbssid_index_ie; 1c8745f3 Johannes Berg 2019-02-07 1541 const struct element *elem, *sub; 1c8745f3 Johannes Berg 2019-02-07 1542 size_t new_ie_len; 0b8fb823 Peng Xu 2019-01-21 1543 u8 new_bssid[ETH_ALEN]; e28e850d Sara Sharon 2019-03-15 1544 u8 *new_ie, *profile; e28e850d Sara Sharon 2019-03-15 1545 u64 seen_indices = 0; 0b8fb823 Peng Xu 2019-01-21 1546 u16 capability; 0b8fb823 Peng Xu 2019-01-21 1547 struct cfg80211_bss *bss; 0b8fb823 Peng Xu 2019-01-21 1548 0cd01efb Sara Sharon 2019-01-22 1549 if (!non_tx_data) 0b8fb823 Peng Xu 2019-01-21 1550 return; 0b8fb823 Peng Xu 2019-01-21 1551 if (!cfg80211_find_ie(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) 0b8fb823 Peng Xu 2019-01-21 1552 return; 213ed579 Sara Sharon 2019-01-16 1553 if (!wiphy->support_mbssid) 213ed579 Sara Sharon 2019-01-16 1554 return; 213ed579 Sara Sharon 2019-01-16 1555 if (wiphy->support_only_he_mbssid && 213ed579 Sara Sharon 2019-01-16 1556 !cfg80211_find_ext_ie(WLAN_EID_EXT_HE_CAPABILITY, ie, ielen)) 213ed579 Sara Sharon 2019-01-16 1557 return; 0b8fb823 Peng Xu 2019-01-21 1558 0b8fb823 Peng Xu 2019-01-21 1559 new_ie = kmalloc(IEEE80211_MAX_DATA_LEN, gfp); 0b8fb823 Peng Xu 2019-01-21 1560 if (!new_ie) 0b8fb823 Peng Xu 2019-01-21 1561 return; 0b8fb823 Peng Xu 2019-01-21 1562 e28e850d Sara Sharon 2019-03-15 1563 profile = kmalloc(ielen, gfp); e28e850d Sara Sharon 2019-03-15 1564 if (!profile) e28e850d Sara Sharon 2019-03-15 1565 goto out; e28e850d Sara Sharon 2019-03-15 1566 1c8745f3 Johannes Berg 2019-02-07 1567 for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { 1c8745f3 Johannes Berg 2019-02-07 1568 if (elem->datalen < 4) 1c8745f3 Johannes Berg 2019-02-07 1569 continue; 1c8745f3 Johannes Berg 2019-02-07 1570 for_each_element(sub, elem->data + 1, elem->datalen - 1) { e28e850d Sara Sharon 2019-03-15 1571 u8 profile_len; e28e850d Sara Sharon 2019-03-15 1572 1c8745f3 Johannes Berg 2019-02-07 1573 if (sub->id != 0 || sub->datalen < 4) { 0b8fb823 Peng Xu 2019-01-21 1574 /* not a valid BSS profile */ 0b8fb823 Peng Xu 2019-01-21 1575 continue; 0b8fb823 Peng Xu 2019-01-21 1576 } 0b8fb823 Peng Xu 2019-01-21 1577 1c8745f3 Johannes Berg 2019-02-07 1578 if (sub->data[0] != WLAN_EID_NON_TX_BSSID_CAP || 1c8745f3 Johannes Berg 2019-02-07 1579 sub->data[1] != 2) { 0b8fb823 Peng Xu 2019-01-21 1580 /* The first element within the Nontransmitted 0b8fb823 Peng Xu 2019-01-21 1581 * BSSID Profile is not the Nontransmitted 0b8fb823 Peng Xu 2019-01-21 1582 * BSSID Capability element. 0b8fb823 Peng Xu 2019-01-21 1583 */ 0b8fb823 Peng Xu 2019-01-21 1584 continue; 0b8fb823 Peng Xu 2019-01-21 1585 } 0b8fb823 Peng Xu 2019-01-21 1586 e28e850d Sara Sharon 2019-03-15 1587 memset(profile, 0, ielen); e28e850d Sara Sharon 2019-03-15 1588 profile_len = cfg80211_merge_profile(ie, ielen, e28e850d Sara Sharon 2019-03-15 1589 elem, e28e850d Sara Sharon 2019-03-15 1590 sub, e28e850d Sara Sharon 2019-03-15 1591 &profile, e28e850d Sara Sharon 2019-03-15 1592 ielen); e28e850d Sara Sharon 2019-03-15 1593 0b8fb823 Peng Xu 2019-01-21 1594 /* found a Nontransmitted BSSID Profile */ 0b8fb823 Peng Xu 2019-01-21 1595 mbssid_index_ie = cfg80211_find_ie 0b8fb823 Peng Xu 2019-01-21 1596 (WLAN_EID_MULTI_BSSID_IDX, e28e850d Sara Sharon 2019-03-15 1597 profile, profile_len); 0b8fb823 Peng Xu 2019-01-21 1598 if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || e28e850d Sara Sharon 2019-03-15 1599 mbssid_index_ie[2] == 0 || e28e850d Sara Sharon 2019-03-15 1600 mbssid_index_ie[2] > 46) { 0b8fb823 Peng Xu 2019-01-21 1601 /* No valid Multiple BSSID-Index element */ 0b8fb823 Peng Xu 2019-01-21 1602 continue; 0b8fb823 Peng Xu 2019-01-21 1603 } 0b8fb823 Peng Xu 2019-01-21 1604 e28e850d Sara Sharon 2019-03-15 1605 if (seen_indices & BIT(mbssid_index_ie[2])) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ I should fix Smatch to generate a warning here as well... e28e850d Sara Sharon 2019-03-15 1606 /* We don't support legacy split of a profile */ e28e850d Sara Sharon 2019-03-15 1607 net_dbg_ratelimited("Partial info for BSSID index %d\n", e28e850d Sara Sharon 2019-03-15 1608 mbssid_index_ie[2]); e28e850d Sara Sharon 2019-03-15 1609 e28e850d Sara Sharon 2019-03-15 @1610 seen_indices |= BIT(mbssid_index_ie[2]); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ e28e850d Sara Sharon 2019-03-15 1611 0cd01efb Sara Sharon 2019-01-22 1612 non_tx_data->bssid_index = mbssid_index_ie[2]; 0cd01efb Sara Sharon 2019-01-22 1613 non_tx_data->max_bssid_indicator = elem->data[0]; 0cd01efb Sara Sharon 2019-01-22 1614 0cd01efb Sara Sharon 2019-01-22 1615 cfg80211_gen_new_bssid(bssid, 0cd01efb Sara Sharon 2019-01-22 1616 non_tx_data->max_bssid_indicator, 0cd01efb Sara Sharon 2019-01-22 1617 non_tx_data->bssid_index, 0b8fb823 Peng Xu 2019-01-21 1618 new_bssid); 0b8fb823 Peng Xu 2019-01-21 1619 memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); e28e850d Sara Sharon 2019-03-15 1620 new_ie_len = cfg80211_gen_new_ie(ie, ielen, e28e850d Sara Sharon 2019-03-15 1621 profile, e28e850d Sara Sharon 2019-03-15 1622 profile_len, new_ie, 0b8fb823 Peng Xu 2019-01-21 1623 gfp); 0b8fb823 Peng Xu 2019-01-21 1624 if (!new_ie_len) 0b8fb823 Peng Xu 2019-01-21 1625 continue; 0b8fb823 Peng Xu 2019-01-21 1626 e28e850d Sara Sharon 2019-03-15 1627 capability = get_unaligned_le16(profile + 2); 0b8fb823 Peng Xu 2019-01-21 1628 bss = cfg80211_inform_single_bss_data(wiphy, data, 0b8fb823 Peng Xu 2019-01-21 1629 ftype, 0b8fb823 Peng Xu 2019-01-21 1630 new_bssid, tsf, 0b8fb823 Peng Xu 2019-01-21 1631 capability, 0b8fb823 Peng Xu 2019-01-21 1632 beacon_interval, 0b8fb823 Peng Xu 2019-01-21 1633 new_ie, 0b8fb823 Peng Xu 2019-01-21 1634 new_ie_len, 0cd01efb Sara Sharon 2019-01-22 1635 non_tx_data, 0cd01efb Sara Sharon 2019-01-22 1636 gfp); 0b8fb823 Peng Xu 2019-01-21 1637 if (!bss) 0b8fb823 Peng Xu 2019-01-21 1638 break; 0b8fb823 Peng Xu 2019-01-21 1639 cfg80211_put_bss(wiphy, bss); 0b8fb823 Peng Xu 2019-01-21 1640 } 0b8fb823 Peng Xu 2019-01-21 1641 } 0b8fb823 Peng Xu 2019-01-21 1642 e28e850d Sara Sharon 2019-03-15 1643 out: 0b8fb823 Peng Xu 2019-01-21 1644 kfree(new_ie); e28e850d Sara Sharon 2019-03-15 1645 kfree(profile); 0b8fb823 Peng Xu 2019-01-21 1646 } 0b8fb823 Peng Xu 2019-01-21 1647 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h index cd47b7085f59..f192c65fe9b4 100644 --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h @@ -5499,6 +5499,20 @@ static inline void cfg80211_gen_new_bssid(const u8 *bssid, u8 max_bssid, bool cfg80211_is_element_inherited(const struct element *element, const struct element *non_inherit_element); +/** + * cfg80211_merge_profile - merges a MBSSID profile if it is split between IEs + * @ie: ies + * @ielen: length of IEs + * @mbssid_elem: current MBSSID element + * @sub_elem: current MBSSID subelement (profile) + * @merged_ie: location of the merged profile + * @max_copy_len: max merged profile length + */ +size_t cfg80211_merge_profile(const u8 *ie, size_t ielen, + const struct element *mbssid_elem, + const struct element *sub_elem, + u8 **merged_ie, size_t max_copy_len); + /** * enum cfg80211_bss_frame_type - frame type that the BSS data came from * @CFG80211_BSS_FTYPE_UNKNOWN: driver doesn't know whether the data is diff --git a/net/wireless/scan.c b/net/wireless/scan.c index bda9114ded77..878c867f3f7d 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1456,6 +1456,78 @@ cfg80211_inform_single_bss_data(struct wiphy *wiphy, return &res->pub; } +static const struct element +*cfg80211_get_profile_continuation(const u8 *ie, size_t ielen, + const struct element *mbssid_elem, + const struct element *sub_elem) +{ + const u8 *mbssid_end = mbssid_elem->data + mbssid_elem->datalen; + const struct element *next_mbssid; + const struct element *next_sub; + + next_mbssid = cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, + mbssid_end, + ielen - (mbssid_end - ie)); + + /* + * If is is not the last subelement in current MBSSID IE or there isn't + * a next MBSSID IE - profile is complete. + */ + if ((sub_elem->data + sub_elem->datalen < mbssid_end - 1) || + !next_mbssid) + return NULL; + + /* For any length error, just return NULL */ + + if (next_mbssid->datalen < 4) + return NULL; + + next_sub = (void *)&next_mbssid->data[1]; + + if (next_mbssid->data + next_mbssid->datalen < + next_sub->data + next_sub->datalen) + return NULL; + + if (next_sub->id != 0 || next_sub->datalen < 2) + return NULL; + + /* + * Check if the first element in the next sub element is a start + * of a new profile + */ + return next_sub->data[0] == WLAN_EID_NON_TX_BSSID_CAP ? + NULL : next_mbssid; +} + +size_t cfg80211_merge_profile(const u8 *ie, size_t ielen, + const struct element *mbssid_elem, + const struct element *sub_elem, + u8 **merged_ie, size_t max_copy_len) +{ + size_t copied_len = sub_elem->datalen; + const struct element *next_mbssid; + + if (sub_elem->datalen > max_copy_len) + return 0; + + memcpy(*merged_ie, sub_elem->data, sub_elem->datalen); + + while ((next_mbssid = cfg80211_get_profile_continuation(ie, ielen, + mbssid_elem, + sub_elem))) { + const struct element *next_sub = (void *)&next_mbssid->data[1]; + + if (copied_len + next_sub->datalen > max_copy_len) + break; + memcpy(*merged_ie + copied_len, next_sub->data, + next_sub->datalen); + copied_len += next_sub->datalen; + } + + return copied_len; +} +EXPORT_SYMBOL(cfg80211_merge_profile); + static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, struct cfg80211_inform_bss *data, enum cfg80211_bss_frame_type ftype, @@ -1469,7 +1541,8 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, const struct element *elem, *sub; size_t new_ie_len; u8 new_bssid[ETH_ALEN]; - u8 *new_ie; + u8 *new_ie, *profile; + u64 seen_indices = 0; u16 capability; struct cfg80211_bss *bss; @@ -1487,10 +1560,16 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, if (!new_ie) return; + profile = kmalloc(ielen, gfp); + if (!profile) + goto out; + for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) { if (elem->datalen < 4) continue; for_each_element(sub, elem->data + 1, elem->datalen - 1) { + u8 profile_len; + if (sub->id != 0 || sub->datalen < 4) { /* not a valid BSS profile */ continue; @@ -1505,16 +1584,31 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, continue; } + memset(profile, 0, ielen); + profile_len = cfg80211_merge_profile(ie, ielen, + elem, + sub, + &profile, + ielen); + /* found a Nontransmitted BSSID Profile */ mbssid_index_ie = cfg80211_find_ie (WLAN_EID_MULTI_BSSID_IDX, - sub->data, sub->datalen); + profile, profile_len); if (!mbssid_index_ie || mbssid_index_ie[1] < 1 || - mbssid_index_ie[2] == 0) { + mbssid_index_ie[2] == 0 || + mbssid_index_ie[2] > 46) { /* No valid Multiple BSSID-Index element */ continue; } + if (seen_indices & BIT(mbssid_index_ie[2])) + /* We don't support legacy split of a profile */ + net_dbg_ratelimited("Partial info for BSSID index %d\n", + mbssid_index_ie[2]); + + seen_indices |= BIT(mbssid_index_ie[2]); + non_tx_data->bssid_index = mbssid_index_ie[2]; non_tx_data->max_bssid_indicator = elem->data[0]; @@ -1523,13 +1617,14 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, non_tx_data->bssid_index, new_bssid); memset(new_ie, 0, IEEE80211_MAX_DATA_LEN); - new_ie_len = cfg80211_gen_new_ie(ie, ielen, sub->data, - sub->datalen, new_ie, + new_ie_len = cfg80211_gen_new_ie(ie, ielen, + profile, + profile_len, new_ie, gfp); if (!new_ie_len) continue; - capability = get_unaligned_le16(sub->data + 2); + capability = get_unaligned_le16(profile + 2); bss = cfg80211_inform_single_bss_data(wiphy, data, ftype, new_bssid, tsf, @@ -1545,7 +1640,9 @@ static void cfg80211_parse_mbssid_data(struct wiphy *wiphy, } } +out: kfree(new_ie); + kfree(profile); } struct cfg80211_bss *