Commit 02f248ea authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'wireless-2022-11-28' of git://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

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.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 4f4a5de1 3e8f7abc
...@@ -17475,10 +17475,8 @@ S: Maintained ...@@ -17475,10 +17475,8 @@ S: Maintained
F: drivers/net/wireless/realtek/rtw89/ F: drivers/net/wireless/realtek/rtw89/
REDPINE WIRELESS DRIVER REDPINE WIRELESS DRIVER
M: Amitkumar Karwar <amitkarwar@gmail.com>
M: Siva Rebbagondla <siva8118@gmail.com>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
S: Maintained S: Orphan
F: drivers/net/wireless/rsi/ F: drivers/net/wireless/rsi/
REGISTER MAP ABSTRACTION REGISTER MAP ABSTRACTION
......
...@@ -959,30 +959,51 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch) ...@@ -959,30 +959,51 @@ static inline void wilc_wfi_cfg_parse_ch_attr(u8 *buf, u32 len, u8 sta_ch)
return; return;
while (index + sizeof(*e) <= len) { while (index + sizeof(*e) <= len) {
u16 attr_size;
e = (struct wilc_attr_entry *)&buf[index]; 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; 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; op_ch_idx = index;
if (ch_list_idx && op_ch_idx) if (ch_list_idx && op_ch_idx)
break; break;
index += le16_to_cpu(e->attr_len) + sizeof(*e);
index += sizeof(*e) + attr_size;
} }
if (ch_list_idx) { if (ch_list_idx) {
u16 attr_size; u16 elem_size;
struct wilc_ch_list_elem *e;
int i;
ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx]; ch_list = (struct wilc_attr_ch_list *)&buf[ch_list_idx];
attr_size = le16_to_cpu(ch_list->attr_len); /* the number of bytes following the final 'elem' member */
for (i = 0; i < attr_size;) { 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); 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) { if (e->op_class == WILC_WLAN_OPERATING_CLASS_2_4GHZ) {
memset(e->ch_list, sta_ch, e->no_of_channels); memset(e->ch_list, sta_ch, e->no_of_channels);
break; break;
} }
i += e->no_of_channels;
} }
} }
......
...@@ -482,14 +482,25 @@ void *wilc_parse_join_bss_param(struct cfg80211_bss *bss, ...@@ -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); rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, ies->data, ies->len);
if (rsn_ie) { if (rsn_ie) {
int rsn_ie_len = sizeof(struct element) + rsn_ie[1];
int offset = 8; int offset = 8;
param->mode_802_11i = 2;
param->rsn_found = true;
/* extract RSN capabilities */ /* extract RSN capabilities */
offset += (rsn_ie[offset] * 4) + 2; if (offset < rsn_ie_len) {
offset += (rsn_ie[offset] * 4) + 2; /* skip over pairwise suites */
memcpy(param->rsn_cap, &rsn_ie[offset], 2); 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) { if (param->rsn_found) {
......
...@@ -452,6 +452,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw, ...@@ -452,6 +452,9 @@ static u32 ieee80211_get_rate_duration(struct ieee80211_hw *hw,
(status->encoding == RX_ENC_HE && streams > 8))) (status->encoding == RX_ENC_HE && streams > 8)))
return 0; return 0;
if (idx >= MCS_GROUP_RATES)
return 0;
duration = airtime_mcs_groups[group].duration[idx]; duration = airtime_mcs_groups[group].duration[idx];
duration <<= airtime_mcs_groups[group].shift; duration <<= airtime_mcs_groups[group].shift;
*overhead = 36 + (streams << 2); *overhead = 36 + (streams << 2);
......
...@@ -330,7 +330,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, ...@@ -330,7 +330,8 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
* determine if they are the same ie. * determine if they are the same ie.
*/ */
if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) { 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 /* same vendor ie, copy from
* subelement * subelement
*/ */
...@@ -2526,10 +2527,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy, ...@@ -2526,10 +2527,15 @@ cfg80211_inform_bss_frame_data(struct wiphy *wiphy,
const struct cfg80211_bss_ies *ies1, *ies2; const struct cfg80211_bss_ies *ies1, *ies2;
size_t ielen = len - offsetof(struct ieee80211_mgmt, size_t ielen = len - offsetof(struct ieee80211_mgmt,
u.probe_resp.variable); 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, res = cfg80211_inform_single_bss_frame_data(wiphy, data, mgmt,
len, gfp); 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 || if (!res || !wiphy->support_mbssid ||
!cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen)) !cfg80211_find_elem(WLAN_EID_MULTIPLE_BSSID, ie, ielen))
return res; return res;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment