• R/O
  • HTTP
  • SSH
  • HTTPS

提交

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Mirror only - Please move to https://github.com/immortalwrt/immortalwrt


Commit MetaInfo

修订版bd2dc958ad68a345410ff05bc55884fa35367708 (tree)
时间2022-10-13 23:24:11
作者Felix Fietkau <nbd@nbd....>
CommiterTianling Shen

Log Message

mac80211: backport security fixes

This mainly affects scanning and beacon parsing, especially with MBSSID enabled

Fixes: CVE-2022-41674
Fixes: CVE-2022-42719
Fixes: CVE-2022-42720
Fixes: CVE-2022-42721
Fixes: CVE-2022-42722
Signed-off-by: Felix Fietkau <nbd@nbd.name>
(cherry picked from commit 26f400210d6b3780fcc0deb89b9741837df9c8b8)

更改概述

差异

--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/346-mac80211-mesh-clean-up-rx_bcn_presp-API.patch
@@ -0,0 +1,110 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Mon, 20 Sep 2021 15:40:07 +0200
3+Subject: [PATCH] mac80211: mesh: clean up rx_bcn_presp API
4+
5+commit a5b983c6073140b624f64e79fea6d33c3e4315a0 upstream.
6+
7+We currently pass the entire elements to the rx_bcn_presp()
8+method, but only need mesh_config. Additionally, we use the
9+length of the elements to calculate back the entire frame's
10+length, but that's confusing - just pass the length of the
11+frame instead.
12+
13+Link: https://lore.kernel.org/r/20210920154009.a18ed3d2da6c.I1824b773a0fbae4453e1433c184678ca14e8df45@changeid
14+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
15+---
16+
17+--- a/net/mac80211/ieee80211_i.h
18++++ b/net/mac80211/ieee80211_i.h
19+@@ -645,10 +645,9 @@ struct ieee80211_if_ocb {
20+ */
21+ struct ieee802_11_elems;
22+ struct ieee80211_mesh_sync_ops {
23+- void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata,
24+- u16 stype,
25+- struct ieee80211_mgmt *mgmt,
26+- struct ieee802_11_elems *elems,
27++ void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata, u16 stype,
28++ struct ieee80211_mgmt *mgmt, unsigned int len,
29++ const struct ieee80211_meshconf_ie *mesh_cfg,
30+ struct ieee80211_rx_status *rx_status);
31+
32+ /* should be called with beacon_data under RCU read lock */
33+--- a/net/mac80211/mesh.c
34++++ b/net/mac80211/mesh.c
35+@@ -1354,8 +1354,8 @@ static void ieee80211_mesh_rx_bcn_presp(
36+ }
37+
38+ if (ifmsh->sync_ops)
39+- ifmsh->sync_ops->rx_bcn_presp(sdata,
40+- stype, mgmt, &elems, rx_status);
41++ ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len,
42++ elems.mesh_config, rx_status);
43+ }
44+
45+ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
46+--- a/net/mac80211/mesh_sync.c
47++++ b/net/mac80211/mesh_sync.c
48+@@ -3,6 +3,7 @@
49+ * Copyright 2011-2012, Pavel Zubarev <pavel.zubarev@gmail.com>
50+ * Copyright 2011-2012, Marco Porsch <marco.porsch@s2005.tu-chemnitz.de>
51+ * Copyright 2011-2012, cozybit Inc.
52++ * Copyright (C) 2021 Intel Corporation
53+ */
54+
55+ #include "ieee80211_i.h"
56+@@ -35,12 +36,12 @@ struct sync_method {
57+ /**
58+ * mesh_peer_tbtt_adjusting - check if an mp is currently adjusting its TBTT
59+ *
60+- * @ie: information elements of a management frame from the mesh peer
61++ * @cfg: mesh config element from the mesh peer (or %NULL)
62+ */
63+-static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
64++static bool mesh_peer_tbtt_adjusting(const struct ieee80211_meshconf_ie *cfg)
65+ {
66+- return (ie->mesh_config->meshconf_cap &
67+- IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
68++ return cfg &&
69++ (cfg->meshconf_cap & IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING);
70+ }
71+
72+ void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata)
73+@@ -76,11 +77,11 @@ void mesh_sync_adjust_tsf(struct ieee802
74+ }
75+ }
76+
77+-static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
78+- u16 stype,
79+- struct ieee80211_mgmt *mgmt,
80+- struct ieee802_11_elems *elems,
81+- struct ieee80211_rx_status *rx_status)
82++static void
83++mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, u16 stype,
84++ struct ieee80211_mgmt *mgmt, unsigned int len,
85++ const struct ieee80211_meshconf_ie *mesh_cfg,
86++ struct ieee80211_rx_status *rx_status)
87+ {
88+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
89+ struct ieee80211_local *local = sdata->local;
90+@@ -101,10 +102,7 @@ static void mesh_sync_offset_rx_bcn_pres
91+ */
92+ if (ieee80211_have_rx_timestamp(rx_status))
93+ t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
94+- 24 + 12 +
95+- elems->total_len +
96+- FCS_LEN,
97+- 24);
98++ len + FCS_LEN, 24);
99+ else
100+ t_r = drv_get_tsf(local, sdata);
101+
102+@@ -119,7 +117,7 @@ static void mesh_sync_offset_rx_bcn_pres
103+ * dot11MeshNbrOffsetMaxNeighbor non-peer non-MBSS neighbors
104+ */
105+
106+- if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) {
107++ if (mesh_peer_tbtt_adjusting(mesh_cfg)) {
108+ msync_dbg(sdata, "STA %pM : is adjusting TBTT\n",
109+ sta->sta.addr);
110+ goto no_sync;
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/347-mac80211-move-CRC-into-struct-ieee802_11_elems.patch
@@ -0,0 +1,82 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Mon, 20 Sep 2021 15:40:08 +0200
3+Subject: [PATCH] mac80211: move CRC into struct ieee802_11_elems
4+
5+commit c6e37ed498f958254b5459253199e816b6bfc52f upstream.
6+
7+We're currently returning this value, but to prepare for
8+returning the allocated structure, move it into there.
9+
10+Link: https://lore.kernel.org/r/20210920154009.479b8ebf999d.If0d4ba75ee38998dc3eeae25058aa748efcb2fc9@changeid
11+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
12+---
13+
14+--- a/net/mac80211/ieee80211_i.h
15++++ b/net/mac80211/ieee80211_i.h
16+@@ -1530,6 +1530,7 @@ struct ieee80211_csa_ie {
17+ struct ieee802_11_elems {
18+ const u8 *ie_start;
19+ size_t total_len;
20++ u32 crc;
21+
22+ /* pointers to IEs */
23+ const struct ieee80211_tdls_lnkie *lnk_id;
24+@@ -2089,10 +2090,10 @@ static inline void ieee80211_tx_skb(stru
25+ ieee80211_tx_skb_tid(sdata, skb, 7);
26+ }
27+
28+-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
29+- struct ieee802_11_elems *elems,
30+- u64 filter, u32 crc, u8 *transmitter_bssid,
31+- u8 *bss_bssid);
32++void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
33++ struct ieee802_11_elems *elems,
34++ u64 filter, u32 crc, u8 *transmitter_bssid,
35++ u8 *bss_bssid);
36+ static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
37+ bool action,
38+ struct ieee802_11_elems *elems,
39+--- a/net/mac80211/mlme.c
40++++ b/net/mac80211/mlme.c
41+@@ -4102,10 +4102,11 @@ static void ieee80211_rx_mgmt_beacon(str
42+ */
43+ if (!ieee80211_is_s1g_beacon(hdr->frame_control))
44+ ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
45+- ncrc = ieee802_11_parse_elems_crc(variable,
46+- len - baselen, false, &elems,
47+- care_about_ies, ncrc,
48+- mgmt->bssid, bssid);
49++ ieee802_11_parse_elems_crc(variable,
50++ len - baselen, false, &elems,
51++ care_about_ies, ncrc,
52++ mgmt->bssid, bssid);
53++ ncrc = elems.crc;
54+
55+ if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
56+ ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) {
57+--- a/net/mac80211/util.c
58++++ b/net/mac80211/util.c
59+@@ -1469,10 +1469,10 @@ static size_t ieee802_11_find_bssid_prof
60+ return found ? profile_len : 0;
61+ }
62+
63+-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
64+- struct ieee802_11_elems *elems,
65+- u64 filter, u32 crc, u8 *transmitter_bssid,
66+- u8 *bss_bssid)
67++void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
68++ struct ieee802_11_elems *elems,
69++ u64 filter, u32 crc, u8 *transmitter_bssid,
70++ u8 *bss_bssid)
71+ {
72+ const struct element *non_inherit = NULL;
73+ u8 *nontransmitted_profile;
74+@@ -1524,7 +1524,7 @@ u32 ieee802_11_parse_elems_crc(const u8
75+
76+ kfree(nontransmitted_profile);
77+
78+- return crc;
79++ elems->crc = crc;
80+ }
81+
82+ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/348-mac80211-mlme-find-auth-challenge-directly.patch
@@ -0,0 +1,80 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Mon, 20 Sep 2021 15:40:09 +0200
3+Subject: [PATCH] mac80211: mlme: find auth challenge directly
4+
5+commit 49a765d6785e99157ff5091cc37485732496864e upstream.
6+
7+There's no need to parse all elements etc. just to find the
8+authentication challenge - use cfg80211_find_elem() instead.
9+This also allows us to remove WLAN_EID_CHALLENGE handling
10+from the element parsing entirely.
11+
12+Link: https://lore.kernel.org/r/20210920154009.45f9b3a15722.Ice3159ffad03a007d6154cbf1fb3a8c48489e86f@changeid
13+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
14+---
15+
16+--- a/net/mac80211/ieee80211_i.h
17++++ b/net/mac80211/ieee80211_i.h
18+@@ -1540,7 +1540,6 @@ struct ieee802_11_elems {
19+ const u8 *supp_rates;
20+ const u8 *ds_params;
21+ const struct ieee80211_tim_ie *tim;
22+- const u8 *challenge;
23+ const u8 *rsn;
24+ const u8 *rsnx;
25+ const u8 *erp_info;
26+@@ -1594,7 +1593,6 @@ struct ieee802_11_elems {
27+ u8 ssid_len;
28+ u8 supp_rates_len;
29+ u8 tim_len;
30+- u8 challenge_len;
31+ u8 rsn_len;
32+ u8 rsnx_len;
33+ u8 ext_supp_rates_len;
34+--- a/net/mac80211/mlme.c
35++++ b/net/mac80211/mlme.c
36+@@ -2889,17 +2889,17 @@ static void ieee80211_auth_challenge(str
37+ {
38+ struct ieee80211_local *local = sdata->local;
39+ struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
40++ const struct element *challenge;
41+ u8 *pos;
42+- struct ieee802_11_elems elems;
43+ u32 tx_flags = 0;
44+ struct ieee80211_prep_tx_info info = {
45+ .subtype = IEEE80211_STYPE_AUTH,
46+ };
47+
48+ pos = mgmt->u.auth.variable;
49+- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems,
50+- mgmt->bssid, auth_data->bss->bssid);
51+- if (!elems.challenge)
52++ challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos,
53++ len - (pos - (u8 *)mgmt));
54++ if (!challenge)
55+ return;
56+ auth_data->expected_transaction = 4;
57+ drv_mgd_prepare_tx(sdata->local, sdata, &info);
58+@@ -2907,7 +2907,8 @@ static void ieee80211_auth_challenge(str
59+ tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
60+ IEEE80211_TX_INTFL_MLME_CONN_TX;
61+ ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0,
62+- elems.challenge - 2, elems.challenge_len + 2,
63++ (void *)challenge,
64++ challenge->datalen + sizeof(*challenge),
65+ auth_data->bss->bssid, auth_data->bss->bssid,
66+ auth_data->key, auth_data->key_len,
67+ auth_data->key_idx, tx_flags);
68+--- a/net/mac80211/util.c
69++++ b/net/mac80211/util.c
70+@@ -1120,10 +1120,6 @@ _ieee802_11_parse_elems_crc(const u8 *st
71+ } else
72+ elem_parse_failed = true;
73+ break;
74+- case WLAN_EID_CHALLENGE:
75+- elems->challenge = pos;
76+- elems->challenge_len = elen;
77+- break;
78+ case WLAN_EID_VENDOR_SPECIFIC:
79+ if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
80+ pos[2] == 0xf2) {
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/349-mac80211-always-allocate-struct-ieee802_11_elems.patch
@@ -0,0 +1,1143 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Mon, 20 Sep 2021 15:40:10 +0200
3+Subject: [PATCH] mac80211: always allocate struct ieee802_11_elems
4+
5+As the 802.11 spec evolves, we need to parse more and more
6+elements. This is causing the struct to grow, and we can no
7+longer get away with putting it on the stack.
8+
9+Change the API to always dynamically allocate and return an
10+allocated pointer that must be kfree()d later.
11+
12+As an alternative, I contemplated a scheme whereby we'd say
13+in the code which elements we needed, e.g.
14+
15+ DECLARE_ELEMENT_PARSER(elems,
16+ SUPPORTED_CHANNELS,
17+ CHANNEL_SWITCH,
18+ EXT(KEY_DELIVERY));
19+
20+ ieee802_11_parse_elems(..., &elems, ...);
21+
22+and while I think this is possible and will save us a lot
23+since most individual places only care about a small subset
24+of the elements, it ended up being a bit more work since a
25+lot of places do the parsing and then pass the struct to
26+other functions, sometimes with multiple levels.
27+
28+Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid
29+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
30+---
31+
32+--- a/net/mac80211/agg-rx.c
33++++ b/net/mac80211/agg-rx.c
34+@@ -478,7 +478,7 @@ void ieee80211_process_addba_request(str
35+ size_t len)
36+ {
37+ u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num;
38+- struct ieee802_11_elems elems = { };
39++ struct ieee802_11_elems *elems = NULL;
40+ u8 dialog_token;
41+ int ies_len;
42+
43+@@ -496,16 +496,17 @@ void ieee80211_process_addba_request(str
44+ ies_len = len - offsetof(struct ieee80211_mgmt,
45+ u.action.u.addba_req.variable);
46+ if (ies_len) {
47+- ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
48+- ies_len, true, &elems, mgmt->bssid, NULL);
49+- if (elems.parse_error)
50++ elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
51++ ies_len, true, mgmt->bssid, NULL);
52++ if (!elems || elems->parse_error)
53+ return;
54+ }
55+
56+ __ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
57+ start_seq_num, ba_policy, tid,
58+ buf_size, true, false,
59+- elems.addba_ext_ie);
60++ elems ? elems->addba_ext_ie : NULL);
61++ kfree(elems);
62+ }
63+
64+ void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
65+--- a/net/mac80211/ibss.c
66++++ b/net/mac80211/ibss.c
67+@@ -9,7 +9,7 @@
68+ * Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
69+ * Copyright 2013-2014 Intel Mobile Communications GmbH
70+ * Copyright(c) 2016 Intel Deutschland GmbH
71+- * Copyright(c) 2018-2020 Intel Corporation
72++ * Copyright(c) 2018-2021 Intel Corporation
73+ */
74+
75+ #include <linux/delay.h>
76+@@ -1589,7 +1589,7 @@ void ieee80211_rx_mgmt_probe_beacon(stru
77+ struct ieee80211_rx_status *rx_status)
78+ {
79+ size_t baselen;
80+- struct ieee802_11_elems elems;
81++ struct ieee802_11_elems *elems;
82+
83+ BUILD_BUG_ON(offsetof(typeof(mgmt->u.probe_resp), variable) !=
84+ offsetof(typeof(mgmt->u.beacon), variable));
85+@@ -1602,10 +1602,14 @@ void ieee80211_rx_mgmt_probe_beacon(stru
86+ if (baselen > len)
87+ return;
88+
89+- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
90+- false, &elems, mgmt->bssid, NULL);
91+-
92+- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
93++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
94++ len - baselen, false,
95++ mgmt->bssid, NULL);
96++
97++ if (elems) {
98++ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, elems);
99++ kfree(elems);
100++ }
101+ }
102+
103+ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
104+@@ -1614,7 +1618,7 @@ void ieee80211_ibss_rx_queued_mgmt(struc
105+ struct ieee80211_rx_status *rx_status;
106+ struct ieee80211_mgmt *mgmt;
107+ u16 fc;
108+- struct ieee802_11_elems elems;
109++ struct ieee802_11_elems *elems;
110+ int ies_len;
111+
112+ rx_status = IEEE80211_SKB_RXCB(skb);
113+@@ -1651,15 +1655,16 @@ void ieee80211_ibss_rx_queued_mgmt(struc
114+ if (ies_len < 0)
115+ break;
116+
117+- ieee802_11_parse_elems(
118++ elems = ieee802_11_parse_elems(
119+ mgmt->u.action.u.chan_switch.variable,
120+- ies_len, true, &elems, mgmt->bssid, NULL);
121++ ies_len, true, mgmt->bssid, NULL);
122+
123+- if (elems.parse_error)
124++ if (!elems || elems->parse_error)
125+ break;
126+
127+ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
128+- rx_status, &elems);
129++ rx_status, elems);
130++ kfree(elems);
131+ break;
132+ }
133+ }
134+--- a/net/mac80211/ieee80211_i.h
135++++ b/net/mac80211/ieee80211_i.h
136+@@ -2088,18 +2088,18 @@ static inline void ieee80211_tx_skb(stru
137+ ieee80211_tx_skb_tid(sdata, skb, 7);
138+ }
139+
140+-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
141+- struct ieee802_11_elems *elems,
142+- u64 filter, u32 crc, u8 *transmitter_bssid,
143+- u8 *bss_bssid);
144+-static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
145+- bool action,
146+- struct ieee802_11_elems *elems,
147+- u8 *transmitter_bssid,
148+- u8 *bss_bssid)
149++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len,
150++ bool action,
151++ u64 filter, u32 crc,
152++ const u8 *transmitter_bssid,
153++ const u8 *bss_bssid);
154++static inline struct ieee802_11_elems *
155++ieee802_11_parse_elems(const u8 *start, size_t len, bool action,
156++ const u8 *transmitter_bssid,
157++ const u8 *bss_bssid)
158+ {
159+- ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0,
160+- transmitter_bssid, bss_bssid);
161++ return ieee802_11_parse_elems_crc(start, len, action, 0, 0,
162++ transmitter_bssid, bss_bssid);
163+ }
164+
165+
166+--- a/net/mac80211/mesh.c
167++++ b/net/mac80211/mesh.c
168+@@ -1247,7 +1247,7 @@ ieee80211_mesh_rx_probe_req(struct ieee8
169+ struct sk_buff *presp;
170+ struct beacon_data *bcn;
171+ struct ieee80211_mgmt *hdr;
172+- struct ieee802_11_elems elems;
173++ struct ieee802_11_elems *elems;
174+ size_t baselen;
175+ u8 *pos;
176+
177+@@ -1256,22 +1256,24 @@ ieee80211_mesh_rx_probe_req(struct ieee8
178+ if (baselen > len)
179+ return;
180+
181+- ieee802_11_parse_elems(pos, len - baselen, false, &elems, mgmt->bssid,
182+- NULL);
183+-
184+- if (!elems.mesh_id)
185++ elems = ieee802_11_parse_elems(pos, len - baselen, false, mgmt->bssid,
186++ NULL);
187++ if (!elems)
188+ return;
189+
190++ if (!elems->mesh_id)
191++ goto free;
192++
193+ /* 802.11-2012 10.1.4.3.2 */
194+ if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) &&
195+ !is_broadcast_ether_addr(mgmt->da)) ||
196+- elems.ssid_len != 0)
197+- return;
198++ elems->ssid_len != 0)
199++ goto free;
200+
201+- if (elems.mesh_id_len != 0 &&
202+- (elems.mesh_id_len != ifmsh->mesh_id_len ||
203+- memcmp(elems.mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len)))
204+- return;
205++ if (elems->mesh_id_len != 0 &&
206++ (elems->mesh_id_len != ifmsh->mesh_id_len ||
207++ memcmp(elems->mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len)))
208++ goto free;
209+
210+ rcu_read_lock();
211+ bcn = rcu_dereference(ifmsh->beacon);
212+@@ -1295,6 +1297,8 @@ ieee80211_mesh_rx_probe_req(struct ieee8
213+ ieee80211_tx_skb(sdata, presp);
214+ out:
215+ rcu_read_unlock();
216++free:
217++ kfree(elems);
218+ }
219+
220+ static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
221+@@ -1305,7 +1309,7 @@ static void ieee80211_mesh_rx_bcn_presp(
222+ {
223+ struct ieee80211_local *local = sdata->local;
224+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
225+- struct ieee802_11_elems elems;
226++ struct ieee802_11_elems *elems;
227+ struct ieee80211_channel *channel;
228+ size_t baselen;
229+ int freq;
230+@@ -1320,42 +1324,47 @@ static void ieee80211_mesh_rx_bcn_presp(
231+ if (baselen > len)
232+ return;
233+
234+- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
235+- false, &elems, mgmt->bssid, NULL);
236++ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
237++ len - baselen,
238++ false, mgmt->bssid, NULL);
239++ if (!elems)
240++ return;
241+
242+ /* ignore non-mesh or secure / unsecure mismatch */
243+- if ((!elems.mesh_id || !elems.mesh_config) ||
244+- (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) ||
245+- (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
246+- return;
247++ if ((!elems->mesh_id || !elems->mesh_config) ||
248++ (elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) ||
249++ (!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
250++ goto free;
251+
252+- if (elems.ds_params)
253+- freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
254++ if (elems->ds_params)
255++ freq = ieee80211_channel_to_frequency(elems->ds_params[0], band);
256+ else
257+ freq = rx_status->freq;
258+
259+ channel = ieee80211_get_channel(local->hw.wiphy, freq);
260+
261+ if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
262+- return;
263++ goto free;
264+
265+- if (mesh_matches_local(sdata, &elems)) {
266++ if (mesh_matches_local(sdata, elems)) {
267+ mpl_dbg(sdata, "rssi_threshold=%d,rx_status->signal=%d\n",
268+ sdata->u.mesh.mshcfg.rssi_threshold, rx_status->signal);
269+ if (!sdata->u.mesh.user_mpm ||
270+ sdata->u.mesh.mshcfg.rssi_threshold == 0 ||
271+ sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
272+- mesh_neighbour_update(sdata, mgmt->sa, &elems,
273++ mesh_neighbour_update(sdata, mgmt->sa, elems,
274+ rx_status);
275+
276+ if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT &&
277+ !sdata->vif.csa_active)
278+- ieee80211_mesh_process_chnswitch(sdata, &elems, true);
279++ ieee80211_mesh_process_chnswitch(sdata, elems, true);
280+ }
281+
282+ if (ifmsh->sync_ops)
283+ ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len,
284+- elems.mesh_config, rx_status);
285++ elems->mesh_config, rx_status);
286++free:
287++ kfree(elems);
288+ }
289+
290+ int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
291+@@ -1447,7 +1456,7 @@ static void mesh_rx_csa_frame(struct iee
292+ struct ieee80211_mgmt *mgmt, size_t len)
293+ {
294+ struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
295+- struct ieee802_11_elems elems;
296++ struct ieee802_11_elems *elems;
297+ u16 pre_value;
298+ bool fwd_csa = true;
299+ size_t baselen;
300+@@ -1460,33 +1469,37 @@ static void mesh_rx_csa_frame(struct iee
301+ pos = mgmt->u.action.u.chan_switch.variable;
302+ baselen = offsetof(struct ieee80211_mgmt,
303+ u.action.u.chan_switch.variable);
304+- ieee802_11_parse_elems(pos, len - baselen, true, &elems,
305+- mgmt->bssid, NULL);
306+-
307+- if (!mesh_matches_local(sdata, &elems))
308++ elems = ieee802_11_parse_elems(pos, len - baselen, true,
309++ mgmt->bssid, NULL);
310++ if (!elems)
311+ return;
312+
313+- ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
314++ if (!mesh_matches_local(sdata, elems))
315++ goto free;
316++
317++ ifmsh->chsw_ttl = elems->mesh_chansw_params_ie->mesh_ttl;
318+ if (!--ifmsh->chsw_ttl)
319+ fwd_csa = false;
320+
321+- pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value);
322++ pre_value = le16_to_cpu(elems->mesh_chansw_params_ie->mesh_pre_value);
323+ if (ifmsh->pre_value >= pre_value)
324+- return;
325++ goto free;
326+
327+ ifmsh->pre_value = pre_value;
328+
329+ if (!sdata->vif.csa_active &&
330+- !ieee80211_mesh_process_chnswitch(sdata, &elems, false)) {
331++ !ieee80211_mesh_process_chnswitch(sdata, elems, false)) {
332+ mcsa_dbg(sdata, "Failed to process CSA action frame");
333+- return;
334++ goto free;
335+ }
336+
337+ /* forward or re-broadcast the CSA frame */
338+ if (fwd_csa) {
339+- if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0)
340++ if (mesh_fwd_csa_frame(sdata, mgmt, len, elems) < 0)
341+ mcsa_dbg(sdata, "Failed to forward the CSA frame");
342+ }
343++free:
344++ kfree(elems);
345+ }
346+
347+ static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
348+--- a/net/mac80211/mesh_hwmp.c
349++++ b/net/mac80211/mesh_hwmp.c
350+@@ -1,7 +1,7 @@
351+ // SPDX-License-Identifier: GPL-2.0-only
352+ /*
353+ * Copyright (c) 2008, 2009 open80211s Ltd.
354+- * Copyright (C) 2019 Intel Corporation
355++ * Copyright (C) 2019, 2021 Intel Corporation
356+ * Author: Luis Carlos Cobo <luisca@cozybit.com>
357+ */
358+
359+@@ -908,7 +908,7 @@ static void hwmp_rann_frame_process(stru
360+ void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
361+ struct ieee80211_mgmt *mgmt, size_t len)
362+ {
363+- struct ieee802_11_elems elems;
364++ struct ieee802_11_elems *elems;
365+ size_t baselen;
366+ u32 path_metric;
367+ struct sta_info *sta;
368+@@ -926,37 +926,41 @@ void mesh_rx_path_sel_frame(struct ieee8
369+ rcu_read_unlock();
370+
371+ baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
372+- ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
373+- len - baselen, false, &elems, mgmt->bssid, NULL);
374++ elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
375++ len - baselen, false, mgmt->bssid, NULL);
376++ if (!elems)
377++ return;
378+
379+- if (elems.preq) {
380+- if (elems.preq_len != 37)
381++ if (elems->preq) {
382++ if (elems->preq_len != 37)
383+ /* Right now we support just 1 destination and no AE */
384+- return;
385+- path_metric = hwmp_route_info_get(sdata, mgmt, elems.preq,
386++ goto free;
387++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->preq,
388+ MPATH_PREQ);
389+ if (path_metric)
390+- hwmp_preq_frame_process(sdata, mgmt, elems.preq,
391++ hwmp_preq_frame_process(sdata, mgmt, elems->preq,
392+ path_metric);
393+ }
394+- if (elems.prep) {
395+- if (elems.prep_len != 31)
396++ if (elems->prep) {
397++ if (elems->prep_len != 31)
398+ /* Right now we support no AE */
399+- return;
400+- path_metric = hwmp_route_info_get(sdata, mgmt, elems.prep,
401++ goto free;
402++ path_metric = hwmp_route_info_get(sdata, mgmt, elems->prep,
403+ MPATH_PREP);
404+ if (path_metric)
405+- hwmp_prep_frame_process(sdata, mgmt, elems.prep,
406++ hwmp_prep_frame_process(sdata, mgmt, elems->prep,
407+ path_metric);
408+ }
409+- if (elems.perr) {
410+- if (elems.perr_len != 15)
411++ if (elems->perr) {
412++ if (elems->perr_len != 15)
413+ /* Right now we support only one destination per PERR */
414+- return;
415+- hwmp_perr_frame_process(sdata, mgmt, elems.perr);
416++ goto free;
417++ hwmp_perr_frame_process(sdata, mgmt, elems->perr);
418+ }
419+- if (elems.rann)
420+- hwmp_rann_frame_process(sdata, mgmt, elems.rann);
421++ if (elems->rann)
422++ hwmp_rann_frame_process(sdata, mgmt, elems->rann);
423++free:
424++ kfree(elems);
425+ }
426+
427+ /**
428+--- a/net/mac80211/mesh_plink.c
429++++ b/net/mac80211/mesh_plink.c
430+@@ -1,7 +1,7 @@
431+ // SPDX-License-Identifier: GPL-2.0-only
432+ /*
433+ * Copyright (c) 2008, 2009 open80211s Ltd.
434+- * Copyright (C) 2019 Intel Corporation
435++ * Copyright (C) 2019, 2021 Intel Corporation
436+ * Author: Luis Carlos Cobo <luisca@cozybit.com>
437+ */
438+ #include <linux/gfp.h>
439+@@ -1200,7 +1200,7 @@ void mesh_rx_plink_frame(struct ieee8021
440+ struct ieee80211_mgmt *mgmt, size_t len,
441+ struct ieee80211_rx_status *rx_status)
442+ {
443+- struct ieee802_11_elems elems;
444++ struct ieee802_11_elems *elems;
445+ size_t baselen;
446+ u8 *baseaddr;
447+
448+@@ -1228,7 +1228,8 @@ void mesh_rx_plink_frame(struct ieee8021
449+ if (baselen > len)
450+ return;
451+ }
452+- ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems,
453+- mgmt->bssid, NULL);
454+- mesh_process_plink_frame(sdata, mgmt, &elems, rx_status);
455++ elems = ieee802_11_parse_elems(baseaddr, len - baselen, true,
456++ mgmt->bssid, NULL);
457++ mesh_process_plink_frame(sdata, mgmt, elems, rx_status);
458++ kfree(elems);
459+ }
460+--- a/net/mac80211/mlme.c
461++++ b/net/mac80211/mlme.c
462+@@ -3317,8 +3317,11 @@ static bool ieee80211_assoc_success(stru
463+ aid = 0; /* TODO */
464+ }
465+ capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
466+- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, elems,
467+- mgmt->bssid, assoc_data->bss->bssid);
468++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false,
469++ mgmt->bssid, assoc_data->bss->bssid);
470++
471++ if (!elems)
472++ return false;
473+
474+ if (elems->aid_resp)
475+ aid = le16_to_cpu(elems->aid_resp->aid);
476+@@ -3340,7 +3343,8 @@ static bool ieee80211_assoc_success(stru
477+
478+ if (!is_s1g && !elems->supp_rates) {
479+ sdata_info(sdata, "no SuppRates element in AssocResp\n");
480+- return false;
481++ ret = false;
482++ goto out;
483+ }
484+
485+ sdata->vif.bss_conf.aid = aid;
486+@@ -3362,7 +3366,7 @@ static bool ieee80211_assoc_success(stru
487+ (!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
488+ (!elems->vht_cap_elem || !elems->vht_operation)))) {
489+ const struct cfg80211_bss_ies *ies;
490+- struct ieee802_11_elems bss_elems;
491++ struct ieee802_11_elems *bss_elems;
492+
493+ rcu_read_lock();
494+ ies = rcu_dereference(cbss->ies);
495+@@ -3373,13 +3377,17 @@ static bool ieee80211_assoc_success(stru
496+ if (!bss_ies)
497+ return false;
498+
499+- ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
500+- false, &bss_elems,
501+- mgmt->bssid,
502+- assoc_data->bss->bssid);
503++ bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
504++ false, mgmt->bssid,
505++ assoc_data->bss->bssid);
506++ if (!bss_elems) {
507++ ret = false;
508++ goto out;
509++ }
510++
511+ if (assoc_data->wmm &&
512+- !elems->wmm_param && bss_elems.wmm_param) {
513+- elems->wmm_param = bss_elems.wmm_param;
514++ !elems->wmm_param && bss_elems->wmm_param) {
515++ elems->wmm_param = bss_elems->wmm_param;
516+ sdata_info(sdata,
517+ "AP bug: WMM param missing from AssocResp\n");
518+ }
519+@@ -3388,30 +3396,32 @@ static bool ieee80211_assoc_success(stru
520+ * Also check if we requested HT/VHT, otherwise the AP doesn't
521+ * have to include the IEs in the (re)association response.
522+ */
523+- if (!elems->ht_cap_elem && bss_elems.ht_cap_elem &&
524++ if (!elems->ht_cap_elem && bss_elems->ht_cap_elem &&
525+ !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
526+- elems->ht_cap_elem = bss_elems.ht_cap_elem;
527++ elems->ht_cap_elem = bss_elems->ht_cap_elem;
528+ sdata_info(sdata,
529+ "AP bug: HT capability missing from AssocResp\n");
530+ }
531+- if (!elems->ht_operation && bss_elems.ht_operation &&
532++ if (!elems->ht_operation && bss_elems->ht_operation &&
533+ !(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
534+- elems->ht_operation = bss_elems.ht_operation;
535++ elems->ht_operation = bss_elems->ht_operation;
536+ sdata_info(sdata,
537+ "AP bug: HT operation missing from AssocResp\n");
538+ }
539+- if (!elems->vht_cap_elem && bss_elems.vht_cap_elem &&
540++ if (!elems->vht_cap_elem && bss_elems->vht_cap_elem &&
541+ !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
542+- elems->vht_cap_elem = bss_elems.vht_cap_elem;
543++ elems->vht_cap_elem = bss_elems->vht_cap_elem;
544+ sdata_info(sdata,
545+ "AP bug: VHT capa missing from AssocResp\n");
546+ }
547+- if (!elems->vht_operation && bss_elems.vht_operation &&
548++ if (!elems->vht_operation && bss_elems->vht_operation &&
549+ !(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
550+- elems->vht_operation = bss_elems.vht_operation;
551++ elems->vht_operation = bss_elems->vht_operation;
552+ sdata_info(sdata,
553+ "AP bug: VHT operation missing from AssocResp\n");
554+ }
555++
556++ kfree(bss_elems);
557+ }
558+
559+ /*
560+@@ -3662,6 +3672,7 @@ static bool ieee80211_assoc_success(stru
561+
562+ ret = true;
563+ out:
564++ kfree(elems);
565+ kfree(bss_ies);
566+ return ret;
567+ }
568+@@ -3673,7 +3684,7 @@ static void ieee80211_rx_mgmt_assoc_resp
569+ struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
570+ struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
571+ u16 capab_info, status_code, aid;
572+- struct ieee802_11_elems elems;
573++ struct ieee802_11_elems *elems;
574+ int ac, uapsd_queues = -1;
575+ u8 *pos;
576+ bool reassoc;
577+@@ -3730,14 +3741,16 @@ static void ieee80211_rx_mgmt_assoc_resp
578+ fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0)
579+ return;
580+
581+- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems,
582+- mgmt->bssid, assoc_data->bss->bssid);
583++ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false,
584++ mgmt->bssid, assoc_data->bss->bssid);
585++ if (!elems)
586++ goto notify_driver;
587+
588+ if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
589+- elems.timeout_int &&
590+- elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
591++ elems->timeout_int &&
592++ elems->timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
593+ u32 tu, ms;
594+- tu = le32_to_cpu(elems.timeout_int->value);
595++ tu = le32_to_cpu(elems->timeout_int->value);
596+ ms = tu * 1024 / 1000;
597+ sdata_info(sdata,
598+ "%pM rejected association temporarily; comeback duration %u TU (%u ms)\n",
599+@@ -3757,7 +3770,7 @@ static void ieee80211_rx_mgmt_assoc_resp
600+ event.u.mlme.reason = status_code;
601+ drv_event_callback(sdata->local, sdata, &event);
602+ } else {
603+- if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, &elems)) {
604++ if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, elems)) {
605+ /* oops -- internal error -- send timeout for now */
606+ ieee80211_destroy_assoc_data(sdata, false, false);
607+ cfg80211_assoc_timeout(sdata->dev, cbss);
608+@@ -3787,6 +3800,7 @@ static void ieee80211_rx_mgmt_assoc_resp
609+ ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len);
610+ notify_driver:
611+ drv_mgd_complete_tx(sdata->local, sdata, &info);
612++ kfree(elems);
613+ }
614+
615+ static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
616+@@ -3991,7 +4005,7 @@ static void ieee80211_rx_mgmt_beacon(str
617+ struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
618+ struct ieee80211_mgmt *mgmt = (void *) hdr;
619+ size_t baselen;
620+- struct ieee802_11_elems elems;
621++ struct ieee802_11_elems *elems;
622+ struct ieee80211_local *local = sdata->local;
623+ struct ieee80211_chanctx_conf *chanctx_conf;
624+ struct ieee80211_channel *chan;
625+@@ -4037,15 +4051,16 @@ static void ieee80211_rx_mgmt_beacon(str
626+
627+ if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
628+ ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) {
629+- ieee802_11_parse_elems(variable,
630+- len - baselen, false, &elems,
631+- bssid,
632+- ifmgd->assoc_data->bss->bssid);
633++ elems = ieee802_11_parse_elems(variable, len - baselen, false,
634++ bssid,
635++ ifmgd->assoc_data->bss->bssid);
636++ if (!elems)
637++ return;
638+
639+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status);
640+
641+- if (elems.dtim_period)
642+- ifmgd->dtim_period = elems.dtim_period;
643++ if (elems->dtim_period)
644++ ifmgd->dtim_period = elems->dtim_period;
645+ ifmgd->have_beacon = true;
646+ ifmgd->assoc_data->need_beacon = false;
647+ if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
648+@@ -4053,17 +4068,17 @@ static void ieee80211_rx_mgmt_beacon(str
649+ le64_to_cpu(mgmt->u.beacon.timestamp);
650+ sdata->vif.bss_conf.sync_device_ts =
651+ rx_status->device_timestamp;
652+- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count;
653++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count;
654+ }
655+
656+- if (elems.mbssid_config_ie)
657++ if (elems->mbssid_config_ie)
658+ bss_conf->profile_periodicity =
659+- elems.mbssid_config_ie->profile_periodicity;
660++ elems->mbssid_config_ie->profile_periodicity;
661+ else
662+ bss_conf->profile_periodicity = 0;
663+
664+- if (elems.ext_capab_len >= 11 &&
665+- (elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
666++ if (elems->ext_capab_len >= 11 &&
667++ (elems->ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
668+ bss_conf->ema_ap = true;
669+ else
670+ bss_conf->ema_ap = false;
671+@@ -4072,6 +4087,7 @@ static void ieee80211_rx_mgmt_beacon(str
672+ ifmgd->assoc_data->timeout = jiffies;
673+ ifmgd->assoc_data->timeout_started = true;
674+ run_again(sdata, ifmgd->assoc_data->timeout);
675++ kfree(elems);
676+ return;
677+ }
678+
679+@@ -4103,14 +4119,15 @@ static void ieee80211_rx_mgmt_beacon(str
680+ */
681+ if (!ieee80211_is_s1g_beacon(hdr->frame_control))
682+ ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
683+- ieee802_11_parse_elems_crc(variable,
684+- len - baselen, false, &elems,
685+- care_about_ies, ncrc,
686+- mgmt->bssid, bssid);
687+- ncrc = elems.crc;
688++ elems = ieee802_11_parse_elems_crc(variable, len - baselen,
689++ false, care_about_ies, ncrc,
690++ mgmt->bssid, bssid);
691++ if (!elems)
692++ return;
693++ ncrc = elems->crc;
694+
695+ if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
696+- ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) {
697++ ieee80211_check_tim(elems->tim, elems->tim_len, bss_conf->aid)) {
698+ if (local->hw.conf.dynamic_ps_timeout > 0) {
699+ if (local->hw.conf.flags & IEEE80211_CONF_PS) {
700+ local->hw.conf.flags &= ~IEEE80211_CONF_PS;
701+@@ -4180,12 +4197,12 @@ static void ieee80211_rx_mgmt_beacon(str
702+ le64_to_cpu(mgmt->u.beacon.timestamp);
703+ sdata->vif.bss_conf.sync_device_ts =
704+ rx_status->device_timestamp;
705+- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count;
706++ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count;
707+ }
708+
709+ if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) ||
710+ ieee80211_is_s1g_short_beacon(mgmt->frame_control))
711+- return;
712++ goto free;
713+ ifmgd->beacon_crc = ncrc;
714+ ifmgd->beacon_crc_valid = true;
715+
716+@@ -4193,12 +4210,12 @@ static void ieee80211_rx_mgmt_beacon(str
717+
718+ ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
719+ rx_status->device_timestamp,
720+- &elems, true);
721++ elems, true);
722+
723+ if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
724+- ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
725+- elems.wmm_param_len,
726+- elems.mu_edca_param_set))
727++ ieee80211_sta_wmm_params(local, sdata, elems->wmm_param,
728++ elems->wmm_param_len,
729++ elems->mu_edca_param_set))
730+ changed |= BSS_CHANGED_QOS;
731+
732+ /*
733+@@ -4207,7 +4224,7 @@ static void ieee80211_rx_mgmt_beacon(str
734+ */
735+ if (!ifmgd->have_beacon) {
736+ /* a few bogus AP send dtim_period = 0 or no TIM IE */
737+- bss_conf->dtim_period = elems.dtim_period ?: 1;
738++ bss_conf->dtim_period = elems->dtim_period ?: 1;
739+
740+ changed |= BSS_CHANGED_BEACON_INFO;
741+ ifmgd->have_beacon = true;
742+@@ -4219,9 +4236,9 @@ static void ieee80211_rx_mgmt_beacon(str
743+ ieee80211_recalc_ps_vif(sdata);
744+ }
745+
746+- if (elems.erp_info) {
747++ if (elems->erp_info) {
748+ erp_valid = true;
749+- erp_value = elems.erp_info[0];
750++ erp_value = elems->erp_info[0];
751+ } else {
752+ erp_valid = false;
753+ }
754+@@ -4234,12 +4251,12 @@ static void ieee80211_rx_mgmt_beacon(str
755+ mutex_lock(&local->sta_mtx);
756+ sta = sta_info_get(sdata, bssid);
757+
758+- changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
759++ changed |= ieee80211_recalc_twt_req(sdata, sta, elems);
760+
761+- if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem,
762+- elems.vht_cap_elem, elems.ht_operation,
763+- elems.vht_operation, elems.he_operation,
764+- elems.s1g_oper, bssid, &changed)) {
765++ if (ieee80211_config_bw(sdata, sta, elems->ht_cap_elem,
766++ elems->vht_cap_elem, elems->ht_operation,
767++ elems->vht_operation, elems->he_operation,
768++ elems->s1g_oper, bssid, &changed)) {
769+ mutex_unlock(&local->sta_mtx);
770+ sdata_info(sdata,
771+ "failed to follow AP %pM bandwidth change, disconnect\n",
772+@@ -4251,21 +4268,23 @@ static void ieee80211_rx_mgmt_beacon(str
773+ sizeof(deauth_buf), true,
774+ WLAN_REASON_DEAUTH_LEAVING,
775+ false);
776+- return;
777++ goto free;
778+ }
779+
780+- if (sta && elems.opmode_notif)
781+- ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
782++ if (sta && elems->opmode_notif)
783++ ieee80211_vht_handle_opmode(sdata, sta, *elems->opmode_notif,
784+ rx_status->band);
785+ mutex_unlock(&local->sta_mtx);
786+
787+ changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
788+- elems.country_elem,
789+- elems.country_elem_len,
790+- elems.pwr_constr_elem,
791+- elems.cisco_dtpc_elem);
792++ elems->country_elem,
793++ elems->country_elem_len,
794++ elems->pwr_constr_elem,
795++ elems->cisco_dtpc_elem);
796+
797+ ieee80211_bss_info_change_notify(sdata, changed);
798++free:
799++ kfree(elems);
800+ }
801+
802+ void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata,
803+@@ -4294,7 +4313,6 @@ void ieee80211_sta_rx_queued_mgmt(struct
804+ struct ieee80211_rx_status *rx_status;
805+ struct ieee80211_mgmt *mgmt;
806+ u16 fc;
807+- struct ieee802_11_elems elems;
808+ int ies_len;
809+
810+ rx_status = (struct ieee80211_rx_status *) skb->cb;
811+@@ -4326,6 +4344,8 @@ void ieee80211_sta_rx_queued_mgmt(struct
812+ break;
813+ case IEEE80211_STYPE_ACTION:
814+ if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
815++ struct ieee802_11_elems *elems;
816++
817+ ies_len = skb->len -
818+ offsetof(struct ieee80211_mgmt,
819+ u.action.u.chan_switch.variable);
820+@@ -4334,18 +4354,21 @@ void ieee80211_sta_rx_queued_mgmt(struct
821+ break;
822+
823+ /* CSA IE cannot be overridden, no need for BSSID */
824+- ieee802_11_parse_elems(
825+- mgmt->u.action.u.chan_switch.variable,
826+- ies_len, true, &elems, mgmt->bssid, NULL);
827++ elems = ieee802_11_parse_elems(
828++ mgmt->u.action.u.chan_switch.variable,
829++ ies_len, true, mgmt->bssid, NULL);
830+
831+- if (elems.parse_error)
832++ if (!elems || elems->parse_error)
833+ break;
834+
835+ ieee80211_sta_process_chanswitch(sdata,
836+ rx_status->mactime,
837+ rx_status->device_timestamp,
838+- &elems, false);
839++ elems, false);
840++ kfree(elems);
841+ } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
842++ struct ieee802_11_elems *elems;
843++
844+ ies_len = skb->len -
845+ offsetof(struct ieee80211_mgmt,
846+ u.action.u.ext_chan_switch.variable);
847+@@ -4357,21 +4380,22 @@ void ieee80211_sta_rx_queued_mgmt(struct
848+ * extended CSA IE can't be overridden, no need for
849+ * BSSID
850+ */
851+- ieee802_11_parse_elems(
852+- mgmt->u.action.u.ext_chan_switch.variable,
853+- ies_len, true, &elems, mgmt->bssid, NULL);
854++ elems = ieee802_11_parse_elems(
855++ mgmt->u.action.u.ext_chan_switch.variable,
856++ ies_len, true, mgmt->bssid, NULL);
857+
858+- if (elems.parse_error)
859++ if (!elems || elems->parse_error)
860+ break;
861+
862+ /* for the handling code pretend this was also an IE */
863+- elems.ext_chansw_ie =
864++ elems->ext_chansw_ie =
865+ &mgmt->u.action.u.ext_chan_switch.data;
866+
867+ ieee80211_sta_process_chanswitch(sdata,
868+ rx_status->mactime,
869+ rx_status->device_timestamp,
870+- &elems, false);
871++ elems, false);
872++ kfree(elems);
873+ }
874+ break;
875+ }
876+--- a/net/mac80211/scan.c
877++++ b/net/mac80211/scan.c
878+@@ -9,7 +9,7 @@
879+ * Copyright 2007, Michael Wu <flamingice@sourmilk.net>
880+ * Copyright 2013-2015 Intel Mobile Communications GmbH
881+ * Copyright 2016-2017 Intel Deutschland GmbH
882+- * Copyright (C) 2018-2020 Intel Corporation
883++ * Copyright (C) 2018-2021 Intel Corporation
884+ */
885+
886+ #include <linux/if_arp.h>
887+@@ -155,7 +155,7 @@ ieee80211_bss_info_update(struct ieee802
888+ };
889+ bool signal_valid;
890+ struct ieee80211_sub_if_data *scan_sdata;
891+- struct ieee802_11_elems elems;
892++ struct ieee802_11_elems *elems;
893+ size_t baselen;
894+ u8 *elements;
895+
896+@@ -209,8 +209,10 @@ ieee80211_bss_info_update(struct ieee802
897+ if (baselen > len)
898+ return NULL;
899+
900+- ieee802_11_parse_elems(elements, len - baselen, false, &elems,
901+- mgmt->bssid, cbss->bssid);
902++ elems = ieee802_11_parse_elems(elements, len - baselen, false,
903++ mgmt->bssid, cbss->bssid);
904++ if (!elems)
905++ return NULL;
906+
907+ /* In case the signal is invalid update the status */
908+ signal_valid = channel == cbss->channel;
909+@@ -218,15 +220,17 @@ ieee80211_bss_info_update(struct ieee802
910+ rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
911+
912+ bss = (void *)cbss->priv;
913+- ieee80211_update_bss_from_elems(local, bss, &elems, rx_status, beacon);
914++ ieee80211_update_bss_from_elems(local, bss, elems, rx_status, beacon);
915+
916+ list_for_each_entry(non_tx_cbss, &cbss->nontrans_list, nontrans_list) {
917+ non_tx_bss = (void *)non_tx_cbss->priv;
918+
919+- ieee80211_update_bss_from_elems(local, non_tx_bss, &elems,
920++ ieee80211_update_bss_from_elems(local, non_tx_bss, elems,
921+ rx_status, beacon);
922+ }
923+
924++ kfree(elems);
925++
926+ return bss;
927+ }
928+
929+--- a/net/mac80211/tdls.c
930++++ b/net/mac80211/tdls.c
931+@@ -6,7 +6,7 @@
932+ * Copyright 2014, Intel Corporation
933+ * Copyright 2014 Intel Mobile Communications GmbH
934+ * Copyright 2015 - 2016 Intel Deutschland GmbH
935+- * Copyright (C) 2019 Intel Corporation
936++ * Copyright (C) 2019, 2021 Intel Corporation
937+ */
938+
939+ #include <linux/ieee80211.h>
940+@@ -1684,7 +1684,7 @@ ieee80211_process_tdls_channel_switch_re
941+ struct sk_buff *skb)
942+ {
943+ struct ieee80211_local *local = sdata->local;
944+- struct ieee802_11_elems elems;
945++ struct ieee802_11_elems *elems = NULL;
946+ struct sta_info *sta;
947+ struct ieee80211_tdls_data *tf = (void *)skb->data;
948+ bool local_initiator;
949+@@ -1718,16 +1718,20 @@ ieee80211_process_tdls_channel_switch_re
950+ goto call_drv;
951+ }
952+
953+- ieee802_11_parse_elems(tf->u.chan_switch_resp.variable,
954+- skb->len - baselen, false, &elems,
955+- NULL, NULL);
956+- if (elems.parse_error) {
957++ elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable,
958++ skb->len - baselen, false, NULL, NULL);
959++ if (!elems) {
960++ ret = -ENOMEM;
961++ goto out;
962++ }
963++
964++ if (elems->parse_error) {
965+ tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n");
966+ ret = -EINVAL;
967+ goto out;
968+ }
969+
970+- if (!elems.ch_sw_timing || !elems.lnk_id) {
971++ if (!elems->ch_sw_timing || !elems->lnk_id) {
972+ tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n");
973+ ret = -EINVAL;
974+ goto out;
975+@@ -1735,15 +1739,15 @@ ieee80211_process_tdls_channel_switch_re
976+
977+ /* validate the initiator is set correctly */
978+ local_initiator =
979+- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
980++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
981+ if (local_initiator == sta->sta.tdls_initiator) {
982+ tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n");
983+ ret = -EINVAL;
984+ goto out;
985+ }
986+
987+- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time);
988+- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout);
989++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time);
990++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout);
991+
992+ params.tmpl_skb =
993+ ieee80211_tdls_ch_sw_resp_tmpl_get(sta, &params.ch_sw_tm_ie);
994+@@ -1763,6 +1767,7 @@ call_drv:
995+ out:
996+ mutex_unlock(&local->sta_mtx);
997+ dev_kfree_skb_any(params.tmpl_skb);
998++ kfree(elems);
999+ return ret;
1000+ }
1001+
1002+@@ -1771,7 +1776,7 @@ ieee80211_process_tdls_channel_switch_re
1003+ struct sk_buff *skb)
1004+ {
1005+ struct ieee80211_local *local = sdata->local;
1006+- struct ieee802_11_elems elems;
1007++ struct ieee802_11_elems *elems;
1008+ struct cfg80211_chan_def chandef;
1009+ struct ieee80211_channel *chan;
1010+ enum nl80211_channel_type chan_type;
1011+@@ -1831,22 +1836,27 @@ ieee80211_process_tdls_channel_switch_re
1012+ return -EINVAL;
1013+ }
1014+
1015+- ieee802_11_parse_elems(tf->u.chan_switch_req.variable,
1016+- skb->len - baselen, false, &elems, NULL, NULL);
1017+- if (elems.parse_error) {
1018++ elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable,
1019++ skb->len - baselen, false, NULL, NULL);
1020++ if (!elems)
1021++ return -ENOMEM;
1022++
1023++ if (elems->parse_error) {
1024+ tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n");
1025+- return -EINVAL;
1026++ ret = -EINVAL;
1027++ goto free;
1028+ }
1029+
1030+- if (!elems.ch_sw_timing || !elems.lnk_id) {
1031++ if (!elems->ch_sw_timing || !elems->lnk_id) {
1032+ tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n");
1033+- return -EINVAL;
1034++ ret = -EINVAL;
1035++ goto free;
1036+ }
1037+
1038+- if (!elems.sec_chan_offs) {
1039++ if (!elems->sec_chan_offs) {
1040+ chan_type = NL80211_CHAN_HT20;
1041+ } else {
1042+- switch (elems.sec_chan_offs->sec_chan_offs) {
1043++ switch (elems->sec_chan_offs->sec_chan_offs) {
1044+ case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
1045+ chan_type = NL80211_CHAN_HT40PLUS;
1046+ break;
1047+@@ -1865,7 +1875,8 @@ ieee80211_process_tdls_channel_switch_re
1048+ if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef,
1049+ sdata->wdev.iftype)) {
1050+ tdls_dbg(sdata, "TDLS chan switch to forbidden channel\n");
1051+- return -EINVAL;
1052++ ret = -EINVAL;
1053++ goto free;
1054+ }
1055+
1056+ mutex_lock(&local->sta_mtx);
1057+@@ -1881,7 +1892,7 @@ ieee80211_process_tdls_channel_switch_re
1058+
1059+ /* validate the initiator is set correctly */
1060+ local_initiator =
1061+- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
1062++ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
1063+ if (local_initiator == sta->sta.tdls_initiator) {
1064+ tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n");
1065+ ret = -EINVAL;
1066+@@ -1889,16 +1900,16 @@ ieee80211_process_tdls_channel_switch_re
1067+ }
1068+
1069+ /* peer should have known better */
1070+- if (!sta->sta.ht_cap.ht_supported && elems.sec_chan_offs &&
1071+- elems.sec_chan_offs->sec_chan_offs) {
1072++ if (!sta->sta.ht_cap.ht_supported && elems->sec_chan_offs &&
1073++ elems->sec_chan_offs->sec_chan_offs) {
1074+ tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n");
1075+ ret = -ENOTSUPP;
1076+ goto out;
1077+ }
1078+
1079+ params.chandef = &chandef;
1080+- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time);
1081+- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout);
1082++ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time);
1083++ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout);
1084+
1085+ params.tmpl_skb =
1086+ ieee80211_tdls_ch_sw_resp_tmpl_get(sta,
1087+@@ -1917,6 +1928,8 @@ ieee80211_process_tdls_channel_switch_re
1088+ out:
1089+ mutex_unlock(&local->sta_mtx);
1090+ dev_kfree_skb_any(params.tmpl_skb);
1091++free:
1092++ kfree(elems);
1093+ return ret;
1094+ }
1095+
1096+--- a/net/mac80211/util.c
1097++++ b/net/mac80211/util.c
1098+@@ -1399,8 +1399,8 @@ _ieee802_11_parse_elems_crc(const u8 *st
1099+
1100+ static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
1101+ struct ieee802_11_elems *elems,
1102+- u8 *transmitter_bssid,
1103+- u8 *bss_bssid,
1104++ const u8 *transmitter_bssid,
1105++ const u8 *bss_bssid,
1106+ u8 *nontransmitted_profile)
1107+ {
1108+ const struct element *elem, *sub;
1109+@@ -1465,16 +1465,20 @@ static size_t ieee802_11_find_bssid_prof
1110+ return found ? profile_len : 0;
1111+ }
1112+
1113+-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
1114+- struct ieee802_11_elems *elems,
1115+- u64 filter, u32 crc, u8 *transmitter_bssid,
1116+- u8 *bss_bssid)
1117++struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len,
1118++ bool action, u64 filter,
1119++ u32 crc,
1120++ const u8 *transmitter_bssid,
1121++ const u8 *bss_bssid)
1122+ {
1123++ struct ieee802_11_elems *elems;
1124+ const struct element *non_inherit = NULL;
1125+ u8 *nontransmitted_profile;
1126+ int nontransmitted_profile_len = 0;
1127+
1128+- memset(elems, 0, sizeof(*elems));
1129++ elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
1130++ if (!elems)
1131++ return NULL;
1132+ elems->ie_start = start;
1133+ elems->total_len = len;
1134+
1135+@@ -1521,6 +1525,8 @@ void ieee802_11_parse_elems_crc(const u8
1136+ kfree(nontransmitted_profile);
1137+
1138+ elems->crc = crc;
1139++
1140++ return elems;
1141+ }
1142+
1143+ void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/350-mac80211-fix-memory-leaks-with-element-parsing.patch
@@ -0,0 +1,115 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Fri, 1 Oct 2021 21:11:08 +0200
3+Subject: [PATCH] mac80211: fix memory leaks with element parsing
4+
5+commit 8223ac199a3849257e86ec27865dc63f034b1cf1 upstream.
6+
7+My previous commit 5d24828d05f3 ("mac80211: always allocate
8+struct ieee802_11_elems") had a few bugs and leaked the new
9+allocated struct in a few error cases, fix that.
10+
11+Fixes: 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems")
12+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
13+Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeid
14+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
15+---
16+
17+--- a/net/mac80211/agg-rx.c
18++++ b/net/mac80211/agg-rx.c
19+@@ -499,13 +499,14 @@ void ieee80211_process_addba_request(str
20+ elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
21+ ies_len, true, mgmt->bssid, NULL);
22+ if (!elems || elems->parse_error)
23+- return;
24++ goto free;
25+ }
26+
27+ __ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
28+ start_seq_num, ba_policy, tid,
29+ buf_size, true, false,
30+ elems ? elems->addba_ext_ie : NULL);
31++free:
32+ kfree(elems);
33+ }
34+
35+--- a/net/mac80211/ibss.c
36++++ b/net/mac80211/ibss.c
37+@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struc
38+ mgmt->u.action.u.chan_switch.variable,
39+ ies_len, true, mgmt->bssid, NULL);
40+
41+- if (!elems || elems->parse_error)
42+- break;
43+-
44+- ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
45+- rx_status, elems);
46++ if (elems && !elems->parse_error)
47++ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt,
48++ skb->len,
49++ rx_status,
50++ elems);
51+ kfree(elems);
52+ break;
53+ }
54+--- a/net/mac80211/mlme.c
55++++ b/net/mac80211/mlme.c
56+@@ -3374,8 +3374,10 @@ static bool ieee80211_assoc_success(stru
57+ bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
58+ GFP_ATOMIC);
59+ rcu_read_unlock();
60+- if (!bss_ies)
61+- return false;
62++ if (!bss_ies) {
63++ ret = false;
64++ goto out;
65++ }
66+
67+ bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
68+ false, mgmt->bssid,
69+@@ -4358,13 +4360,11 @@ void ieee80211_sta_rx_queued_mgmt(struct
70+ mgmt->u.action.u.chan_switch.variable,
71+ ies_len, true, mgmt->bssid, NULL);
72+
73+- if (!elems || elems->parse_error)
74+- break;
75+-
76+- ieee80211_sta_process_chanswitch(sdata,
77+- rx_status->mactime,
78+- rx_status->device_timestamp,
79+- elems, false);
80++ if (elems && !elems->parse_error)
81++ ieee80211_sta_process_chanswitch(sdata,
82++ rx_status->mactime,
83++ rx_status->device_timestamp,
84++ elems, false);
85+ kfree(elems);
86+ } else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
87+ struct ieee802_11_elems *elems;
88+@@ -4384,17 +4384,17 @@ void ieee80211_sta_rx_queued_mgmt(struct
89+ mgmt->u.action.u.ext_chan_switch.variable,
90+ ies_len, true, mgmt->bssid, NULL);
91+
92+- if (!elems || elems->parse_error)
93+- break;
94++ if (elems && !elems->parse_error) {
95++ /* for the handling code pretend it was an IE */
96++ elems->ext_chansw_ie =
97++ &mgmt->u.action.u.ext_chan_switch.data;
98++
99++ ieee80211_sta_process_chanswitch(sdata,
100++ rx_status->mactime,
101++ rx_status->device_timestamp,
102++ elems, false);
103++ }
104+
105+- /* for the handling code pretend this was also an IE */
106+- elems->ext_chansw_ie =
107+- &mgmt->u.action.u.ext_chan_switch.data;
108+-
109+- ieee80211_sta_process_chanswitch(sdata,
110+- rx_status->mactime,
111+- rx_status->device_timestamp,
112+- elems, false);
113+ kfree(elems);
114+ }
115+ break;
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/351-wifi-cfg80211-fix-u8-overflow-in-cfg80211_update_not.patch
@@ -0,0 +1,41 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Wed, 28 Sep 2022 21:56:15 +0200
3+Subject: [PATCH] wifi: cfg80211: fix u8 overflow in
4+ cfg80211_update_notlisted_nontrans()
5+
6+commit aebe9f4639b13a1f4e9a6b42cdd2e38c617b442d upstream.
7+
8+In the copy code of the elements, we do the following calculation
9+to reach the end of the MBSSID element:
10+
11+ /* copy the IEs after MBSSID */
12+ cpy_len = mbssid[1] + 2;
13+
14+This looks fine, however, cpy_len is a u8, the same as mbssid[1],
15+so the addition of two can overflow. In this case the subsequent
16+memcpy() will overflow the allocated buffer, since it copies 256
17+bytes too much due to the way the allocation and memcpy() sizes
18+are calculated.
19+
20+Fix this by using size_t for the cpy_len variable.
21+
22+This fixes CVE-2022-41674.
23+
24+Reported-by: Soenke Huster <shuster@seemoo.tu-darmstadt.de>
25+Tested-by: Soenke Huster <shuster@seemoo.tu-darmstadt.de>
26+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
27+Reviewed-by: Kees Cook <keescook@chromium.org>
28+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
29+---
30+
31+--- a/net/wireless/scan.c
32++++ b/net/wireless/scan.c
33+@@ -2238,7 +2238,7 @@ cfg80211_update_notlisted_nontrans(struc
34+ size_t new_ie_len;
35+ struct cfg80211_bss_ies *new_ies;
36+ const struct cfg80211_bss_ies *old;
37+- u8 cpy_len;
38++ size_t cpy_len;
39+
40+ lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);
41+
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/352-wifi-cfg80211-mac80211-reject-bad-MBSSID-elements.patch
@@ -0,0 +1,47 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Wed, 28 Sep 2022 22:01:37 +0200
3+Subject: [PATCH] wifi: cfg80211/mac80211: reject bad MBSSID elements
4+
5+commit 8f033d2becc24aa6bfd2a5c104407963560caabc upstream
6+
7+Per spec, the maximum value for the MaxBSSID ('n') indicator is 8,
8+and the minimum is 1 since a multiple BSSID set with just one BSSID
9+doesn't make sense (the # of BSSIDs is limited by 2^n).
10+
11+Limit this in the parsing in both cfg80211 and mac80211, rejecting
12+any elements with an invalid value.
13+
14+This fixes potentially bad shifts in the processing of these inside
15+the cfg80211_gen_new_bssid() function later.
16+
17+I found this during the investigation of CVE-2022-41674 fixed by the
18+previous patch.
19+
20+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
21+Fixes: 78ac51f81532 ("mac80211: support multi-bssid")
22+Reviewed-by: Kees Cook <keescook@chromium.org>
23+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
24+---
25+
26+--- a/net/mac80211/util.c
27++++ b/net/mac80211/util.c
28+@@ -1413,6 +1413,8 @@ static size_t ieee802_11_find_bssid_prof
29+ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
30+ if (elem->datalen < 2)
31+ continue;
32++ if (elem->data[0] < 1 || elem->data[0] > 8)
33++ continue;
34+
35+ for_each_element(sub, elem->data + 1, elem->datalen - 1) {
36+ u8 new_bssid[ETH_ALEN];
37+--- a/net/wireless/scan.c
38++++ b/net/wireless/scan.c
39+@@ -2103,6 +2103,8 @@ static void cfg80211_parse_mbssid_data(s
40+ for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
41+ if (elem->datalen < 4)
42+ continue;
43++ if (elem->data[0] < 1 || (int)elem->data[0] > 8)
44++ continue;
45+ for_each_element(sub, elem->data + 1, elem->datalen - 1) {
46+ u8 profile_len;
47+
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/353-wifi-mac80211-fix-MBSSID-parsing-use-after-free.patch
@@ -0,0 +1,94 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Wed, 28 Sep 2022 22:07:15 +0200
3+Subject: [PATCH] wifi: mac80211: fix MBSSID parsing use-after-free
4+
5+commit ff05d4b45dd89b922578dac497dcabf57cf771c6
6+
7+When we parse a multi-BSSID element, we might point some
8+element pointers into the allocated nontransmitted_profile.
9+However, we free this before returning, causing UAF when the
10+relevant pointers in the parsed elements are accessed.
11+
12+Fix this by not allocating the scratch buffer separately but
13+as part of the returned structure instead, that way, there
14+are no lifetime issues with it.
15+
16+The scratch buffer introduction as part of the returned data
17+here is taken from MLO feature work done by Ilan.
18+
19+This fixes CVE-2022-42719.
20+
21+Fixes: 5023b14cf4df ("mac80211: support profile split between elements")
22+Co-developed-by: Ilan Peer <ilan.peer@intel.com>
23+Signed-off-by: Ilan Peer <ilan.peer@intel.com>
24+Reviewed-by: Kees Cook <keescook@chromium.org>
25+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
26+---
27+
28+--- a/net/mac80211/ieee80211_i.h
29++++ b/net/mac80211/ieee80211_i.h
30+@@ -1611,6 +1611,14 @@ struct ieee802_11_elems {
31+
32+ /* whether a parse error occurred while retrieving these elements */
33+ bool parse_error;
34++
35++ /*
36++ * scratch buffer that can be used for various element parsing related
37++ * tasks, e.g., element de-fragmentation etc.
38++ */
39++ size_t scratch_len;
40++ u8 *scratch_pos;
41++ u8 scratch[];
42+ };
43+
44+ static inline struct ieee80211_local *hw_to_local(
45+--- a/net/mac80211/util.c
46++++ b/net/mac80211/util.c
47+@@ -1478,24 +1478,25 @@ struct ieee802_11_elems *ieee802_11_pars
48+ u8 *nontransmitted_profile;
49+ int nontransmitted_profile_len = 0;
50+
51+- elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
52++ elems = kzalloc(sizeof(*elems) + len, GFP_ATOMIC);
53+ if (!elems)
54+ return NULL;
55+ elems->ie_start = start;
56+ elems->total_len = len;
57+
58+- nontransmitted_profile = kmalloc(len, GFP_ATOMIC);
59+- if (nontransmitted_profile) {
60+- nontransmitted_profile_len =
61+- ieee802_11_find_bssid_profile(start, len, elems,
62+- transmitter_bssid,
63+- bss_bssid,
64+- nontransmitted_profile);
65+- non_inherit =
66+- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
67+- nontransmitted_profile,
68+- nontransmitted_profile_len);
69+- }
70++ elems->scratch_len = len;
71++ elems->scratch_pos = elems->scratch;
72++
73++ nontransmitted_profile = elems->scratch_pos;
74++ nontransmitted_profile_len =
75++ ieee802_11_find_bssid_profile(start, len, elems,
76++ transmitter_bssid,
77++ bss_bssid,
78++ nontransmitted_profile);
79++ non_inherit =
80++ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
81++ nontransmitted_profile,
82++ nontransmitted_profile_len);
83+
84+ crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
85+ crc, non_inherit);
86+@@ -1524,8 +1525,6 @@ struct ieee802_11_elems *ieee802_11_pars
87+ offsetofend(struct ieee80211_bssid_index, dtim_count))
88+ elems->dtim_count = elems->bssid_index->dtim_count;
89+
90+- kfree(nontransmitted_profile);
91+-
92+ elems->crc = crc;
93+
94+ return elems;
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/354-wifi-cfg80211-ensure-length-byte-is-present-before-a.patch
@@ -0,0 +1,41 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Thu, 29 Sep 2022 21:50:44 +0200
3+Subject: [PATCH] wifi: cfg80211: ensure length byte is present before
4+ access
5+
6+commit 567e14e39e8f8c6997a1378bc3be615afca86063 upstream.
7+
8+When iterating the elements here, ensure the length byte is
9+present before checking it to see if the entire element will
10+fit into the buffer.
11+
12+Longer term, we should rewrite this code using the type-safe
13+element iteration macros that check all of this.
14+
15+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
16+Reported-by: Soenke Huster <shuster@seemoo.tu-darmstadt.de>
17+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
18+---
19+
20+--- a/net/wireless/scan.c
21++++ b/net/wireless/scan.c
22+@@ -304,7 +304,8 @@ static size_t cfg80211_gen_new_ie(const
23+ tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
24+ tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
25+
26+- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
27++ while (tmp_old + 2 - ie <= ielen &&
28++ tmp_old + tmp_old[1] + 2 - ie <= ielen) {
29+ if (tmp_old[0] == 0) {
30+ tmp_old++;
31+ continue;
32+@@ -364,7 +365,8 @@ static size_t cfg80211_gen_new_ie(const
33+ * copied to new ie, skip ssid, capability, bssid-index ie
34+ */
35+ tmp_new = sub_copy;
36+- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
37++ while (tmp_new + 2 - sub_copy <= subie_len &&
38++ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
39+ if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
40+ tmp_new[0] == WLAN_EID_SSID)) {
41+ memcpy(pos, tmp_new, tmp_new[1] + 2);
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/355-wifi-cfg80211-fix-BSS-refcounting-bugs.patch
@@ -0,0 +1,87 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Fri, 30 Sep 2022 23:44:23 +0200
3+Subject: [PATCH] wifi: cfg80211: fix BSS refcounting bugs
4+MIME-Version: 1.0
5+Content-Type: text/plain; charset=UTF-8
6+Content-Transfer-Encoding: 8bit
7+
8+commit 0b7808818cb9df6680f98996b8e9a439fa7bcc2f upstream.
9+
10+There are multiple refcounting bugs related to multi-BSSID:
11+ - In bss_ref_get(), if the BSS has a hidden_beacon_bss, then
12+ the bss pointer is overwritten before checking for the
13+ transmitted BSS, which is clearly wrong. Fix this by using
14+ the bss_from_pub() macro.
15+
16+ - In cfg80211_bss_update() we copy the transmitted_bss pointer
17+ from tmp into new, but then if we release new, we'll unref
18+ it erroneously. We already set the pointer and ref it, but
19+ need to NULL it since it was copied from the tmp data.
20+
21+ - In cfg80211_inform_single_bss_data(), if adding to the non-
22+ transmitted list fails, we unlink the BSS and yet still we
23+ return it, but this results in returning an entry without
24+ a reference. We shouldn't return it anyway if it was broken
25+ enough to not get added there.
26+
27+This fixes CVE-2022-42720.
28+
29+Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
30+Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
31+Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS")
32+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
33+---
34+
35+--- a/net/wireless/scan.c
36++++ b/net/wireless/scan.c
37+@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cf
38+ lockdep_assert_held(&rdev->bss_lock);
39+
40+ bss->refcount++;
41+- if (bss->pub.hidden_beacon_bss) {
42+- bss = container_of(bss->pub.hidden_beacon_bss,
43+- struct cfg80211_internal_bss,
44+- pub);
45+- bss->refcount++;
46+- }
47+- if (bss->pub.transmitted_bss) {
48+- bss = container_of(bss->pub.transmitted_bss,
49+- struct cfg80211_internal_bss,
50+- pub);
51+- bss->refcount++;
52+- }
53++
54++ if (bss->pub.hidden_beacon_bss)
55++ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
56++
57++ if (bss->pub.transmitted_bss)
58++ bss_from_pub(bss->pub.transmitted_bss)->refcount++;
59+ }
60+
61+ static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
62+@@ -1743,6 +1737,8 @@ cfg80211_bss_update(struct cfg80211_regi
63+ new->refcount = 1;
64+ INIT_LIST_HEAD(&new->hidden_list);
65+ INIT_LIST_HEAD(&new->pub.nontrans_list);
66++ /* we'll set this later if it was non-NULL */
67++ new->pub.transmitted_bss = NULL;
68+
69+ if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
70+ hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
71+@@ -1983,10 +1979,15 @@ cfg80211_inform_single_bss_data(struct w
72+ spin_lock_bh(&rdev->bss_lock);
73+ if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
74+ &res->pub)) {
75+- if (__cfg80211_unlink_bss(rdev, res))
76++ if (__cfg80211_unlink_bss(rdev, res)) {
77+ rdev->bss_generation++;
78++ res = NULL;
79++ }
80+ }
81+ spin_unlock_bh(&rdev->bss_lock);
82++
83++ if (!res)
84++ return NULL;
85+ }
86+
87+ trace_cfg80211_return_bss(&res->pub);
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/356-wifi-cfg80211-avoid-nontransmitted-BSS-list-corrupti.patch
@@ -0,0 +1,48 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Sat, 1 Oct 2022 00:01:44 +0200
3+Subject: [PATCH] wifi: cfg80211: avoid nontransmitted BSS list
4+ corruption
5+MIME-Version: 1.0
6+Content-Type: text/plain; charset=UTF-8
7+Content-Transfer-Encoding: 8bit
8+
9+commit bcca852027e5878aec911a347407ecc88d6fff7f upstream.
10+
11+If a non-transmitted BSS shares enough information (both
12+SSID and BSSID!) with another non-transmitted BSS of a
13+different AP, then we can find and update it, and then
14+try to add it to the non-transmitted BSS list. We do a
15+search for it on the transmitted BSS, but if it's not
16+there (but belongs to another transmitted BSS), the list
17+gets corrupted.
18+
19+Since this is an erroneous situation, simply fail the
20+list insertion in this case and free the non-transmitted
21+BSS.
22+
23+This fixes CVE-2022-42721.
24+
25+Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
26+Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
27+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
28+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
29+---
30+
31+--- a/net/wireless/scan.c
32++++ b/net/wireless/scan.c
33+@@ -425,6 +425,15 @@ cfg80211_add_nontrans_list(struct cfg802
34+
35+ rcu_read_unlock();
36+
37++ /*
38++ * This is a bit weird - it's not on the list, but already on another
39++ * one! The only way that could happen is if there's some BSSID/SSID
40++ * shared by multiple APs in their multi-BSSID profiles, potentially
41++ * with hidden SSID mixed in ... ignore it.
42++ */
43++ if (!list_empty(&nontrans_bss->nontrans_list))
44++ return -EINVAL;
45++
46+ /* add to the list */
47+ list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
48+ return 0;
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/357-wifi-mac80211_hwsim-avoid-mac80211-warning-on-bad-ra.patch
@@ -0,0 +1,31 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Wed, 5 Oct 2022 15:10:09 +0200
3+Subject: [PATCH] wifi: mac80211_hwsim: avoid mac80211 warning on bad
4+ rate
5+MIME-Version: 1.0
6+Content-Type: text/plain; charset=UTF-8
7+Content-Transfer-Encoding: 8bit
8+
9+commit 1833b6f46d7e2830251a063935ab464256defe22 upstream.
10+
11+If the tool on the other side (e.g. wmediumd) gets confused
12+about the rate, we hit a warning in mac80211. Silence that
13+by effectively duplicating the check here and dropping the
14+frame silently (in mac80211 it's dropped with the warning).
15+
16+Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
17+Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
18+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
19+---
20+
21+--- a/drivers/net/wireless/mac80211_hwsim.c
22++++ b/drivers/net/wireless/mac80211_hwsim.c
23+@@ -3760,6 +3760,8 @@ static int hwsim_cloned_frame_received_n
24+
25+ rx_status.band = channel->band;
26+ rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
27++ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
28++ goto out;
29+ rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
30+
31+ hdr = (void *)skb->data;
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/358-wifi-mac80211-fix-crash-in-beacon-protection-for-P2P.patch
@@ -0,0 +1,52 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Wed, 5 Oct 2022 21:24:10 +0200
3+Subject: [PATCH] wifi: mac80211: fix crash in beacon protection for
4+ P2P-device
5+MIME-Version: 1.0
6+Content-Type: text/plain; charset=UTF-8
7+Content-Transfer-Encoding: 8bit
8+
9+commit b2d03cabe2b2e150ff5a381731ea0355459be09f upstream.
10+
11+If beacon protection is active but the beacon cannot be
12+decrypted or is otherwise malformed, we call the cfg80211
13+API to report this to userspace, but that uses a netdev
14+pointer, which isn't present for P2P-Device. Fix this to
15+call it only conditionally to ensure cfg80211 won't crash
16+in the case of P2P-Device.
17+
18+This fixes CVE-2022-42722.
19+
20+Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
21+Fixes: 9eaf183af741 ("mac80211: Report beacon protection failures to user space")
22+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
23+---
24+
25+--- a/net/mac80211/rx.c
26++++ b/net/mac80211/rx.c
27+@@ -1986,10 +1986,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_
28+
29+ if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS ||
30+ mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
31+- NUM_DEFAULT_BEACON_KEYS) {
32+- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
33+- skb->data,
34+- skb->len);
35++ NUM_DEFAULT_BEACON_KEYS) {
36++ if (rx->sdata->dev)
37++ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
38++ skb->data,
39++ skb->len);
40+ return RX_DROP_MONITOR; /* unexpected BIP keyidx */
41+ }
42+
43+@@ -2137,7 +2138,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_
44+ /* either the frame has been decrypted or will be dropped */
45+ status->flag |= RX_FLAG_DECRYPTED;
46+
47+- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE))
48++ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE &&
49++ rx->sdata->dev))
50+ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
51+ skb->data, skb->len);
52+
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch
@@ -0,0 +1,85 @@
1+From: Johannes Berg <johannes.berg@intel.com>
2+Date: Wed, 5 Oct 2022 23:11:43 +0200
3+Subject: [PATCH] wifi: cfg80211: update hidden BSSes to avoid WARN_ON
4+MIME-Version: 1.0
5+Content-Type: text/plain; charset=UTF-8
6+Content-Transfer-Encoding: 8bit
7+
8+commit c90b93b5b782891ebfda49d4e5da36632fefd5d1 upstream.
9+
10+When updating beacon elements in a non-transmitted BSS,
11+also update the hidden sub-entries to the same beacon
12+elements, so that a future update through other paths
13+won't trigger a WARN_ON().
14+
15+The warning is triggered because the beacon elements in
16+the hidden BSSes that are children of the BSS should
17+always be the same as in the parent.
18+
19+Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
20+Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
21+Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
22+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
23+---
24+
25+--- a/net/wireless/scan.c
26++++ b/net/wireless/scan.c
27+@@ -1609,6 +1609,23 @@ struct cfg80211_non_tx_bss {
28+ u8 bssid_index;
29+ };
30+
31++static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
32++ const struct cfg80211_bss_ies *new_ies,
33++ const struct cfg80211_bss_ies *old_ies)
34++{
35++ struct cfg80211_internal_bss *bss;
36++
37++ /* Assign beacon IEs to all sub entries */
38++ list_for_each_entry(bss, &known->hidden_list, hidden_list) {
39++ const struct cfg80211_bss_ies *ies;
40++
41++ ies = rcu_access_pointer(bss->pub.beacon_ies);
42++ WARN_ON(ies != old_ies);
43++
44++ rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
45++ }
46++}
47++
48+ static bool
49+ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
50+ struct cfg80211_internal_bss *known,
51+@@ -1632,7 +1649,6 @@ cfg80211_update_known_bss(struct cfg8021
52+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
53+ } else if (rcu_access_pointer(new->pub.beacon_ies)) {
54+ const struct cfg80211_bss_ies *old;
55+- struct cfg80211_internal_bss *bss;
56+
57+ if (known->pub.hidden_beacon_bss &&
58+ !list_empty(&known->hidden_list)) {
59+@@ -1660,16 +1676,7 @@ cfg80211_update_known_bss(struct cfg8021
60+ if (old == rcu_access_pointer(known->pub.ies))
61+ rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
62+
63+- /* Assign beacon IEs to all sub entries */
64+- list_for_each_entry(bss, &known->hidden_list, hidden_list) {
65+- const struct cfg80211_bss_ies *ies;
66+-
67+- ies = rcu_access_pointer(bss->pub.beacon_ies);
68+- WARN_ON(ies != old);
69+-
70+- rcu_assign_pointer(bss->pub.beacon_ies,
71+- new->pub.beacon_ies);
72+- }
73++ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
74+
75+ if (old)
76+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
77+@@ -2319,6 +2326,8 @@ cfg80211_update_notlisted_nontrans(struc
78+ } else {
79+ old = rcu_access_pointer(nontrans_bss->beacon_ies);
80+ rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
81++ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
82++ new_ies, old);
83+ rcu_assign_pointer(nontrans_bss->ies, new_ies);
84+ if (old)
85+ kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
--- a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch
+++ b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-Fix-UAF-in-ieee80211_scan_rx.patch
@@ -29,7 +29,7 @@ Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2929
3030 --- a/net/mac80211/scan.c
3131 +++ b/net/mac80211/scan.c
32-@@ -461,16 +461,19 @@ static void __ieee80211_scan_completed(s
32+@@ -465,16 +465,19 @@ static void __ieee80211_scan_completed(s
3333 scan_req = rcu_dereference_protected(local->scan_req,
3434 lockdep_is_held(&local->mtx));
3535
--- a/package/kernel/mac80211/patches/subsys/350-bss-color-collision.patch
+++ b/package/kernel/mac80211/patches/subsys/363-bss-color-collision.patch
@@ -56,7 +56,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
5656
5757 --- a/net/mac80211/rx.c
5858 +++ b/net/mac80211/rx.c
59-@@ -3180,6 +3180,49 @@ static void ieee80211_process_sa_query_r
59+@@ -3182,6 +3182,49 @@ static void ieee80211_process_sa_query_r
6060 ieee80211_tx_skb(sdata, skb);
6161 }
6262
@@ -106,7 +106,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
106106 static ieee80211_rx_result debug_noinline
107107 ieee80211_rx_h_mgmt_check(struct ieee80211_rx_data *rx)
108108 {
109-@@ -3205,6 +3248,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802
109+@@ -3207,6 +3250,9 @@ ieee80211_rx_h_mgmt_check(struct ieee802
110110 !(rx->flags & IEEE80211_RX_BEACON_REPORTED)) {
111111 int sig = 0;
112112