OSDN Git Service

Merge tag 'wireless-2022-11-28' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorJakub Kicinski <kuba@kernel.org>
Tue, 29 Nov 2022 01:58:45 +0000 (17:58 -0800)
committerJakub Kicinski <kuba@kernel.org>
Tue, 29 Nov 2022 01:58:46 +0000 (17:58 -0800)
Kalle Valo says:

====================
wireless fixes for v6.1

Third, and hopefully final, set of fixes for v6.1. We are marking the
rsi driver as orphan, have some Information Element parsing fixes to
wilc1000 driver and three small fixes to the stack.

* tag 'wireless-2022-11-28' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: mac8021: fix possible oob access in ieee80211_get_rate_duration
  wifi: cfg80211: don't allow multi-BSSID in S1G
  wifi: cfg80211: fix buffer overflow in elem comparison
  wifi: wilc1000: validate number of channels
  wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_CHANNEL_LIST attribute
  wifi: wilc1000: validate length of IEEE80211_P2P_ATTR_OPER_CHANNEL attribute
  wifi: wilc1000: validate pairwise and authentication suite offsets
  MAINTAINERS: mark rsi wifi driver as orphan
====================

Link: https://lore.kernel.org/r/20221128113513.6F459C433C1@smtp.kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
MAINTAINERS
drivers/net/wireless/microchip/wilc1000/cfg80211.c
drivers/net/wireless/microchip/wilc1000/hif.c
net/mac80211/airtime.c
net/wireless/scan.c

index 256f039..4a203c5 100644 (file)
@@ -17475,10 +17475,8 @@ S:     Maintained
 F:     drivers/net/wireless/realtek/rtw89/
 
 REDPINE WIRELESS DRIVER
-M:     Amitkumar Karwar <amitkarwar@gmail.com>
-M:     Siva Rebbagondla <siva8118@gmail.com>
 L:     linux-wireless@vger.kernel.org
-S:     Maintained
+S:     Orphan
 F:     drivers/net/wireless/rsi/
 
 REGISTER MAP ABSTRACTION
index 9bbfff8..b545d93 100644 (file)
@@ -959,30 +959,51 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
                return;
 
        while (index + sizeof(*e) <= len) {
+               u16 attr_size;
+
                e = (struct wilc_attr_entry *)&buf[index];
-               if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST)
+               attr_size = le16_to_cpu(e->attr_len);
+
+               if (index + sizeof(*e) + attr_size > len)
+                       return;
+
+               if (e->attr_type == IEEE80211_P2P_ATTR_CHANNEL_LIST &&
+                   attr_size >= (sizeof(struct wilc_attr_ch_list) - sizeof(*e)))
                        ch_list_idx = index;
-               else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL)
+               else if (e->attr_type == IEEE80211_P2P_ATTR_OPER_CHANNEL &&
+                        attr_size == (sizeof(struct wilc_attr_oper_ch) - sizeof(*e)))
                        op_ch_idx = index;
+
                if (ch_list_idx && op_ch_idx)
                        break;
-               index += le16_to_cpu(e->attr_len) + sizeof(*e);
+
+               index += sizeof(*e) + attr_size;
        }
 
        if (ch_list_idx) {
-               u16 attr_size;
-               struct wilc_ch_list_elem *e;
-               int i;
+               u16 elem_size;
 
                ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
-               attr_size = le16_to_cpu(ch_list->attr_len);
-               for (i = 0; i < attr_size;) {
+               /* the number of bytes following the final 'elem' member */
+               elem_size = le16_to_cpu(ch_list->attr_len) -
+                       (sizeof(*ch_list) - sizeof(struct wilc_attr_entry));
+               for (unsigned int i = 0; i < elem_size;) {
+                       struct wilc_ch_list_elem *e;
+
                        e = (struct wilc_ch_list_elem *)(ch_list->elem + i);
+
+                       i += sizeof(*e);
+                       if (i > elem_size)
+                               break;
+
+                       i += e->no_of_channels;
+                       if (i > elem_size)
+                               break;
+
                        if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
                                memset(e->ch_list, sta_ch, e->no_of_channels);
                                break;
                        }
-                       i += e->no_of_channels;
                }
        }
 
index eb1d1ba..67df822 100644 (file)
@@ -482,14 +482,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss,
 
        rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
        if (rsn_ie) {
+               int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
                int offset = 8;
 
-               param->mode_802_11i = 2;
-               param->rsn_found = true;
                /* extract RSN capabilities */
-               offset += (rsn_ie[offset] * 4) + 2;
-               offset += (rsn_ie[offset] * 4) + 2;
-               memcpy(param->rsn_cap, &rsn_ie[offset], 2);
+               if (offset < rsn_ie_len) {
+                       /* skip over pairwise suites */
+                       offset += (rsn_ie[offset] * 4) + 2;
+
+                       if (offset < rsn_ie_len) {
+                               /* skip over authentication suites */
+                               offset += (rsn_ie[offset] * 4) + 2;
+
+                               if (offset + 1 < rsn_ie_len) {
+                                       param->mode_802_11i = 2;
+                                       param->rsn_found = true;
+                                       memcpy(param->rsn_cap, &rsn_ie[offset], 2);
+                               }
+                       }
+               }
        }
 
        if (param->rsn_found) {
index 2e66598..e8ebd34 100644 (file)
@@ -452,6 +452,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
                         (status->encoding == RX_ENC_HE && streams > 8)))
                return 0;
 
+       if (idx >= MCS_GROUP_RATES)
+               return 0;
+
        duration = airtime_mcs_groups[group].duration[idx];
        duration <<= airtime_mcs_groups[group].shift;
        *overhead = 36 + (streams << 2);
index da752b0..3d86482 100644 (file)
@@ -330,7 +330,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
                         * determine if they are the same ie.
                         */
                        if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
-                               if (!memcmp(tmp_old + 2, tmp + 2, 5)) {
+                               if (tmp_old[1] >= 5 && tmp[1] >= 5 &&
+                                   !memcmp(tmp_old + 2, tmp + 2, 5)) {
                                        /* same vendor ie, copy from
                                         * subelement
                                         */
@@ -2526,10 +2527,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
        const struct cfg80211_bss_ies *ies1, *ies2;
        size_t ielen = len - offsetof(struct ieee80211_mgmt,
                                      u.probe_resp.variable);
-       struct cfg80211_non_tx_bss non_tx_data;
+       struct cfg80211_non_tx_bss non_tx_data = {};
 
        res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
                                                    len, gfp);
+
+       /* don't do any further MBSSID handling for S1G */
+       if (ieee80211_is_s1g_beacon(mgmt->frame_control))
+               return res;
+
        if (!res || !wiphy->support_mbssid ||
            !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
                return res;