|
Takashi Iwai |
8eb966 |
From 5d24828d05f37ad770599de00b53d5386e35aa61 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
8eb966 |
From: Johannes Berg <johannes.berg@intel.com>
|
|
Takashi Iwai |
8eb966 |
Date: Mon, 20 Sep 2021 15:40:10 +0200
|
|
Takashi Iwai |
8eb966 |
Subject: [PATCH] mac80211: always allocate struct ieee802_11_elems
|
|
Takashi Iwai |
8eb966 |
Git-commit: 5d24828d05f37ad770599de00b53d5386e35aa61
|
|
Takashi Iwai |
8eb966 |
Patch-mainline: v5.16-rc1
|
|
Takashi Iwai |
8eb966 |
References: CVE-2022-42719 bsc#1204051
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
As the 802.11 spec evolves, we need to parse more and more
|
|
Takashi Iwai |
8eb966 |
elements. This is causing the struct to grow, and we can no
|
|
Takashi Iwai |
8eb966 |
longer get away with putting it on the stack.
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
Change the API to always dynamically allocate and return an
|
|
Takashi Iwai |
8eb966 |
allocated pointer that must be kfree()d later.
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
As an alternative, I contemplated a scheme whereby we'd say
|
|
Takashi Iwai |
8eb966 |
in the code which elements we needed, e.g.
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
DECLARE_ELEMENT_PARSER(elems,
|
|
Takashi Iwai |
8eb966 |
SUPPORTED_CHANNELS,
|
|
Takashi Iwai |
8eb966 |
CHANNEL_SWITCH,
|
|
Takashi Iwai |
8eb966 |
EXT(KEY_DELIVERY));
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee802_11_parse_elems(..., &elems, ...);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
and while I think this is possible and will save us a lot
|
|
Takashi Iwai |
8eb966 |
since most individual places only care about a small subset
|
|
Takashi Iwai |
8eb966 |
of the elements, it ended up being a bit more work since a
|
|
Takashi Iwai |
8eb966 |
lot of places do the parsing and then pass the struct to
|
|
Takashi Iwai |
8eb966 |
other functions, sometimes with multiple levels.
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
Link: https://lore.kernel.org/r/20210920154009.26caff6b5998.I05ae58768e990e611aee8eca8abefd9d7bc15e05@changeid
|
|
Takashi Iwai |
8eb966 |
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
Takashi Iwai |
8eb966 |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
---
|
|
Takashi Iwai |
8eb966 |
net/mac80211/agg-rx.c | 11 +-
|
|
Takashi Iwai |
8eb966 |
net/mac80211/ibss.c | 27 ++++--
|
|
Takashi Iwai |
8eb966 |
net/mac80211/ieee80211_i.h | 22 ++---
|
|
Takashi Iwai |
8eb966 |
net/mac80211/mesh.c | 86 ++++++++++++---------
|
|
Takashi Iwai |
8eb966 |
net/mac80211/mesh_hwmp.c | 44 ++++++-----
|
|
Takashi Iwai |
8eb966 |
net/mac80211/mesh_plink.c | 11 +-
|
|
Takashi Iwai |
8eb966 |
net/mac80211/mlme.c | 176 +++++++++++++++++++++++++--------------------
|
|
Takashi Iwai |
8eb966 |
net/mac80211/scan.c | 16 ++--
|
|
Takashi Iwai |
8eb966 |
net/mac80211/tdls.c | 63 +++++++++-------
|
|
Takashi Iwai |
8eb966 |
net/mac80211/util.c | 20 +++--
|
|
Takashi Iwai |
8eb966 |
10 files changed, 274 insertions(+), 202 deletions(-)
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/agg-rx.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/agg-rx.c
|
|
Takashi Iwai |
8eb966 |
@@ -478,7 +478,7 @@ void ieee80211_process_addba_request(str
|
|
Takashi Iwai |
8eb966 |
size_t len)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
u16 capab, tid, timeout, ba_policy, buf_size, start_seq_num;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems = { };
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems = NULL;
|
|
Takashi Iwai |
8eb966 |
u8 dialog_token;
|
|
Takashi Iwai |
8eb966 |
int ies_len;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -496,16 +496,17 @@ void ieee80211_process_addba_request(str
|
|
Takashi Iwai |
8eb966 |
ies_len = len - offsetof(struct ieee80211_mgmt,
|
|
Takashi Iwai |
8eb966 |
u.action.u.addba_req.variable);
|
|
Takashi Iwai |
8eb966 |
if (ies_len) {
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
|
|
Takashi Iwai |
8eb966 |
- ies_len, true, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
- if (elems.parse_error)
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
|
|
Takashi Iwai |
8eb966 |
+ ies_len, true, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems || elems->parse_error)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
__ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
|
|
Takashi Iwai |
8eb966 |
start_seq_num, ba_policy, tid,
|
|
Takashi Iwai |
8eb966 |
buf_size, true, false,
|
|
Takashi Iwai |
8eb966 |
- elems.addba_ext_ie);
|
|
Takashi Iwai |
8eb966 |
+ elems ? elems->addba_ext_ie : NULL);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
void ieee80211_manage_rx_ba_offl(struct ieee80211_vif *vif,
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/ibss.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/ibss.c
|
|
Takashi Iwai |
8eb966 |
@@ -9,7 +9,7 @@
|
|
Takashi Iwai |
8eb966 |
* Copyright 2009, Johannes Berg <johannes@sipsolutions.net>
|
|
Takashi Iwai |
8eb966 |
* Copyright 2013-2014 Intel Mobile Communications GmbH
|
|
Takashi Iwai |
8eb966 |
* Copyright(c) 2016 Intel Deutschland GmbH
|
|
Takashi Iwai |
8eb966 |
- * Copyright(c) 2018-2020 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
+ * Copyright(c) 2018-2021 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
#include <linux/delay.h>
|
|
Takashi Iwai |
8eb966 |
@@ -1600,7 +1600,7 @@ void ieee80211_rx_mgmt_probe_beacon(stru
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_rx_status *rx_status)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
BUILD_BUG_ON(offsetof(typeof(mgmt->u.probe_resp), variable) !=
|
|
Takashi Iwai |
8eb966 |
offsetof(typeof(mgmt->u.beacon), variable));
|
|
Takashi Iwai |
8eb966 |
@@ -1613,10 +1613,14 @@ void ieee80211_rx_mgmt_probe_beacon(stru
|
|
Takashi Iwai |
8eb966 |
if (baselen > len)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
|
|
Takashi Iwai |
8eb966 |
- false, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
-
|
|
Takashi Iwai |
8eb966 |
- ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, &elems);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
|
|
Takashi Iwai |
8eb966 |
+ len - baselen, false,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ if (elems) {
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_rx_bss_info(sdata, mgmt, len, rx_status, elems);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
+ }
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
8eb966 |
@@ -1625,7 +1629,7 @@ void ieee80211_ibss_rx_queued_mgmt(struc
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_rx_status *rx_status;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *mgmt;
|
|
Takashi Iwai |
8eb966 |
u16 fc;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
int ies_len;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
rx_status = IEEE80211_SKB_RXCB(skb);
|
|
Takashi Iwai |
8eb966 |
@@ -1662,15 +1666,16 @@ void ieee80211_ibss_rx_queued_mgmt(struc
|
|
Takashi Iwai |
8eb966 |
if (ies_len < 0)
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(
|
|
Takashi Iwai |
8eb966 |
mgmt->u.action.u.chan_switch.variable,
|
|
Takashi Iwai |
8eb966 |
- ies_len, true, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ ies_len, true, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.parse_error)
|
|
Takashi Iwai |
8eb966 |
+ if (!elems || elems->parse_error)
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
|
|
Takashi Iwai |
8eb966 |
- rx_status, &elems);
|
|
Takashi Iwai |
8eb966 |
+ rx_status, elems);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/ieee80211_i.h
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/ieee80211_i.h
|
|
Takashi Iwai |
8eb966 |
@@ -2197,18 +2197,18 @@ static inline void ieee80211_tx_skb(stru
|
|
Takashi Iwai |
8eb966 |
ieee80211_tx_skb_tid(sdata, skb, 7);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems *elems,
|
|
Takashi Iwai |
8eb966 |
- u64 filter, u32 crc, u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
- u8 *bss_bssid);
|
|
Takashi Iwai |
8eb966 |
-static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
|
|
Takashi Iwai |
8eb966 |
- bool action,
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems *elems,
|
|
Takashi Iwai |
8eb966 |
- u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
- u8 *bss_bssid)
|
|
Takashi Iwai |
8eb966 |
+struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len,
|
|
Takashi Iwai |
8eb966 |
+ bool action,
|
|
Takashi Iwai |
8eb966 |
+ u64 filter, u32 crc,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *bss_bssid);
|
|
Takashi Iwai |
8eb966 |
+static inline struct ieee802_11_elems *
|
|
Takashi Iwai |
8eb966 |
+ieee802_11_parse_elems(const u8 *start, size_t len, bool action,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *bss_bssid)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems_crc(start, len, action, elems, 0, 0,
|
|
Takashi Iwai |
8eb966 |
- transmitter_bssid, bss_bssid);
|
|
Takashi Iwai |
8eb966 |
+ return ieee802_11_parse_elems_crc(start, len, action, 0, 0,
|
|
Takashi Iwai |
8eb966 |
+ transmitter_bssid, bss_bssid);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/mesh.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/mesh.c
|
|
Takashi Iwai |
8eb966 |
@@ -1247,7 +1247,7 @@ ieee80211_mesh_rx_probe_req(struct ieee8
|
|
Takashi Iwai |
8eb966 |
struct sk_buff *presp;
|
|
Takashi Iwai |
8eb966 |
struct beacon_data *bcn;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *hdr;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
u8 *pos;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -1256,22 +1256,24 @@ ieee80211_mesh_rx_probe_req(struct ieee8
|
|
Takashi Iwai |
8eb966 |
if (baselen > len)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(pos, len - baselen, false, &elems, mgmt->bssid,
|
|
Takashi Iwai |
8eb966 |
- NULL);
|
|
Takashi Iwai |
8eb966 |
-
|
|
Takashi Iwai |
8eb966 |
- if (!elems.mesh_id)
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(pos, len - baselen, false, mgmt->bssid,
|
|
Takashi Iwai |
8eb966 |
+ NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->mesh_id)
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
/* 802.11-2012 10.1.4.3.2 */
|
|
Takashi Iwai |
8eb966 |
if ((!ether_addr_equal(mgmt->da, sdata->vif.addr) &&
|
|
Takashi Iwai |
8eb966 |
!is_broadcast_ether_addr(mgmt->da)) ||
|
|
Takashi Iwai |
8eb966 |
- elems.ssid_len != 0)
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ elems->ssid_len != 0)
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.mesh_id_len != 0 &&
|
|
Takashi Iwai |
8eb966 |
- (elems.mesh_id_len != ifmsh->mesh_id_len ||
|
|
Takashi Iwai |
8eb966 |
- memcmp(elems.mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len)))
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ if (elems->mesh_id_len != 0 &&
|
|
Takashi Iwai |
8eb966 |
+ (elems->mesh_id_len != ifmsh->mesh_id_len ||
|
|
Takashi Iwai |
8eb966 |
+ memcmp(elems->mesh_id, ifmsh->mesh_id, ifmsh->mesh_id_len)))
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
rcu_read_lock();
|
|
Takashi Iwai |
8eb966 |
bcn = rcu_dereference(ifmsh->beacon);
|
|
Takashi Iwai |
8eb966 |
@@ -1295,6 +1297,8 @@ ieee80211_mesh_rx_probe_req(struct ieee8
|
|
Takashi Iwai |
8eb966 |
ieee80211_tx_skb(sdata, presp);
|
|
Takashi Iwai |
8eb966 |
out:
|
|
Takashi Iwai |
8eb966 |
rcu_read_unlock();
|
|
Takashi Iwai |
8eb966 |
+free:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
static void ieee80211_mesh_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
8eb966 |
@@ -1305,7 +1309,7 @@ static void ieee80211_mesh_rx_bcn_presp(
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_local *local = sdata->local;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_channel *channel;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
int freq;
|
|
Takashi Iwai |
8eb966 |
@@ -1320,42 +1324,48 @@ static void ieee80211_mesh_rx_bcn_presp(
|
|
Takashi Iwai |
8eb966 |
if (baselen > len)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(mgmt->u.probe_resp.variable, len - baselen,
|
|
Takashi Iwai |
8eb966 |
- false, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(mgmt->u.probe_resp.variable,
|
|
Takashi Iwai |
8eb966 |
+ len - baselen,
|
|
Takashi Iwai |
8eb966 |
+ false, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* ignore non-mesh or secure / unsecure mismatch */
|
|
Takashi Iwai |
8eb966 |
- if ((!elems.mesh_id || !elems.mesh_config) ||
|
|
Takashi Iwai |
8eb966 |
- (elems.rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) ||
|
|
Takashi Iwai |
8eb966 |
- (!elems.rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ if ((!elems->mesh_id || !elems->mesh_config) ||
|
|
Takashi Iwai |
8eb966 |
+ (elems->rsn && sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) ||
|
|
Takashi Iwai |
8eb966 |
+ (!elems->rsn && sdata->u.mesh.security != IEEE80211_MESH_SEC_NONE))
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.ds_params)
|
|
Takashi Iwai |
8eb966 |
- freq = ieee80211_channel_to_frequency(elems.ds_params[0], band);
|
|
Takashi Iwai |
8eb966 |
+ if (elems->ds_params)
|
|
Takashi Iwai |
8eb966 |
+ freq = ieee80211_channel_to_frequency(elems->ds_params[0], band);
|
|
Takashi Iwai |
8eb966 |
else
|
|
Takashi Iwai |
8eb966 |
freq = rx_status->freq;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
channel = ieee80211_get_channel(local->hw.wiphy, freq);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (!channel || channel->flags & IEEE80211_CHAN_DISABLED)
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (mesh_matches_local(sdata, &elems)) {
|
|
Takashi Iwai |
8eb966 |
+ if (mesh_matches_local(sdata, elems)) {
|
|
Takashi Iwai |
8eb966 |
mpl_dbg(sdata, "rssi_threshold=%d,rx_status->signal=%d\n",
|
|
Takashi Iwai |
8eb966 |
sdata->u.mesh.mshcfg.rssi_threshold, rx_status->signal);
|
|
Takashi Iwai |
8eb966 |
if (!sdata->u.mesh.user_mpm ||
|
|
Takashi Iwai |
8eb966 |
sdata->u.mesh.mshcfg.rssi_threshold == 0 ||
|
|
Takashi Iwai |
8eb966 |
sdata->u.mesh.mshcfg.rssi_threshold < rx_status->signal)
|
|
Takashi Iwai |
8eb966 |
- mesh_neighbour_update(sdata, mgmt->sa, &elems,
|
|
Takashi Iwai |
8eb966 |
+ mesh_neighbour_update(sdata, mgmt->sa, elems,
|
|
Takashi Iwai |
8eb966 |
rx_status);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (ifmsh->csa_role != IEEE80211_MESH_CSA_ROLE_INIT &&
|
|
Takashi Iwai |
8eb966 |
!sdata->vif.csa_active)
|
|
Takashi Iwai |
8eb966 |
- ieee80211_mesh_process_chnswitch(sdata, &elems, true);
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_mesh_process_chnswitch(sdata, elems, true);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (ifmsh->sync_ops)
|
|
Takashi Iwai |
8eb966 |
ifmsh->sync_ops->rx_bcn_presp(sdata,
|
|
Takashi Iwai |
8eb966 |
- stype, mgmt, &elems, rx_status);
|
|
Takashi Iwai |
8eb966 |
+ stype, mgmt, elems, rx_status);
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+free:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
|
|
Takashi Iwai |
8eb966 |
@@ -1447,7 +1457,7 @@ static void mesh_rx_csa_frame(struct iee
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *mgmt, size_t len)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
u16 pre_value;
|
|
Takashi Iwai |
8eb966 |
bool fwd_csa = true;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
@@ -1460,33 +1470,37 @@ static void mesh_rx_csa_frame(struct iee
|
|
Takashi Iwai |
8eb966 |
pos = mgmt->u.action.u.chan_switch.variable;
|
|
Takashi Iwai |
8eb966 |
baselen = offsetof(struct ieee80211_mgmt,
|
|
Takashi Iwai |
8eb966 |
u.action.u.chan_switch.variable);
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(pos, len - baselen, true, &elems,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
-
|
|
Takashi Iwai |
8eb966 |
- if (!mesh_matches_local(sdata, &elems))
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(pos, len - baselen, true,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ifmsh->chsw_ttl = elems.mesh_chansw_params_ie->mesh_ttl;
|
|
Takashi Iwai |
8eb966 |
+ if (!mesh_matches_local(sdata, elems))
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ ifmsh->chsw_ttl = elems->mesh_chansw_params_ie->mesh_ttl;
|
|
Takashi Iwai |
8eb966 |
if (!--ifmsh->chsw_ttl)
|
|
Takashi Iwai |
8eb966 |
fwd_csa = false;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- pre_value = le16_to_cpu(elems.mesh_chansw_params_ie->mesh_pre_value);
|
|
Takashi Iwai |
8eb966 |
+ pre_value = le16_to_cpu(elems->mesh_chansw_params_ie->mesh_pre_value);
|
|
Takashi Iwai |
8eb966 |
if (ifmsh->pre_value >= pre_value)
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ifmsh->pre_value = pre_value;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (!sdata->vif.csa_active &&
|
|
Takashi Iwai |
8eb966 |
- !ieee80211_mesh_process_chnswitch(sdata, &elems, false)) {
|
|
Takashi Iwai |
8eb966 |
+ !ieee80211_mesh_process_chnswitch(sdata, elems, false)) {
|
|
Takashi Iwai |
8eb966 |
mcsa_dbg(sdata, "Failed to process CSA action frame");
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* forward or re-broadcast the CSA frame */
|
|
Takashi Iwai |
8eb966 |
if (fwd_csa) {
|
|
Takashi Iwai |
8eb966 |
- if (mesh_fwd_csa_frame(sdata, mgmt, len, &elems) < 0)
|
|
Takashi Iwai |
8eb966 |
+ if (mesh_fwd_csa_frame(sdata, mgmt, len, elems) < 0)
|
|
Takashi Iwai |
8eb966 |
mcsa_dbg(sdata, "Failed to forward the CSA frame");
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
+free:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
static void ieee80211_mesh_rx_mgmt_action(struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/mesh_hwmp.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/mesh_hwmp.c
|
|
Takashi Iwai |
8eb966 |
@@ -1,7 +1,7 @@
|
|
Takashi Iwai |
8eb966 |
// SPDX-License-Identifier: GPL-2.0-only
|
|
Takashi Iwai |
8eb966 |
/*
|
|
Takashi Iwai |
8eb966 |
* Copyright (c) 2008, 2009 open80211s Ltd.
|
|
Takashi Iwai |
8eb966 |
- * Copyright (C) 2019 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
+ * Copyright (C) 2019, 2021 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
* Author: Luis Carlos Cobo <luisca@cozybit.com>
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -908,7 +908,7 @@ static void hwmp_rann_frame_process(stru
|
|
Takashi Iwai |
8eb966 |
void mesh_rx_path_sel_frame(struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *mgmt, size_t len)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
u32 path_metric;
|
|
Takashi Iwai |
8eb966 |
struct sta_info *sta;
|
|
Takashi Iwai |
8eb966 |
@@ -926,37 +926,41 @@ void mesh_rx_path_sel_frame(struct ieee8
|
|
Takashi Iwai |
8eb966 |
rcu_read_unlock();
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
baselen = (u8 *) mgmt->u.action.u.mesh_action.variable - (u8 *) mgmt;
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
|
|
Takashi Iwai |
8eb966 |
- len - baselen, false, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(mgmt->u.action.u.mesh_action.variable,
|
|
Takashi Iwai |
8eb966 |
+ len - baselen, false, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.preq) {
|
|
Takashi Iwai |
8eb966 |
- if (elems.preq_len != 37)
|
|
Takashi Iwai |
8eb966 |
+ if (elems->preq) {
|
|
Takashi Iwai |
8eb966 |
+ if (elems->preq_len != 37)
|
|
Takashi Iwai |
8eb966 |
/* Right now we support just 1 destination and no AE */
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
- path_metric = hwmp_route_info_get(sdata, mgmt, elems.preq,
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
+ path_metric = hwmp_route_info_get(sdata, mgmt, elems->preq,
|
|
Takashi Iwai |
8eb966 |
MPATH_PREQ);
|
|
Takashi Iwai |
8eb966 |
if (path_metric)
|
|
Takashi Iwai |
8eb966 |
- hwmp_preq_frame_process(sdata, mgmt, elems.preq,
|
|
Takashi Iwai |
8eb966 |
+ hwmp_preq_frame_process(sdata, mgmt, elems->preq,
|
|
Takashi Iwai |
8eb966 |
path_metric);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- if (elems.prep) {
|
|
Takashi Iwai |
8eb966 |
- if (elems.prep_len != 31)
|
|
Takashi Iwai |
8eb966 |
+ if (elems->prep) {
|
|
Takashi Iwai |
8eb966 |
+ if (elems->prep_len != 31)
|
|
Takashi Iwai |
8eb966 |
/* Right now we support no AE */
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
- path_metric = hwmp_route_info_get(sdata, mgmt, elems.prep,
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
+ path_metric = hwmp_route_info_get(sdata, mgmt, elems->prep,
|
|
Takashi Iwai |
8eb966 |
MPATH_PREP);
|
|
Takashi Iwai |
8eb966 |
if (path_metric)
|
|
Takashi Iwai |
8eb966 |
- hwmp_prep_frame_process(sdata, mgmt, elems.prep,
|
|
Takashi Iwai |
8eb966 |
+ hwmp_prep_frame_process(sdata, mgmt, elems->prep,
|
|
Takashi Iwai |
8eb966 |
path_metric);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- if (elems.perr) {
|
|
Takashi Iwai |
8eb966 |
- if (elems.perr_len != 15)
|
|
Takashi Iwai |
8eb966 |
+ if (elems->perr) {
|
|
Takashi Iwai |
8eb966 |
+ if (elems->perr_len != 15)
|
|
Takashi Iwai |
8eb966 |
/* Right now we support only one destination per PERR */
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
- hwmp_perr_frame_process(sdata, mgmt, elems.perr);
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
+ hwmp_perr_frame_process(sdata, mgmt, elems->perr);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- if (elems.rann)
|
|
Takashi Iwai |
8eb966 |
- hwmp_rann_frame_process(sdata, mgmt, elems.rann);
|
|
Takashi Iwai |
8eb966 |
+ if (elems->rann)
|
|
Takashi Iwai |
8eb966 |
+ hwmp_rann_frame_process(sdata, mgmt, elems->rann);
|
|
Takashi Iwai |
8eb966 |
+free:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/**
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/mesh_plink.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/mesh_plink.c
|
|
Takashi Iwai |
8eb966 |
@@ -1,7 +1,7 @@
|
|
Takashi Iwai |
8eb966 |
// SPDX-License-Identifier: GPL-2.0-only
|
|
Takashi Iwai |
8eb966 |
/*
|
|
Takashi Iwai |
8eb966 |
* Copyright (c) 2008, 2009 open80211s Ltd.
|
|
Takashi Iwai |
8eb966 |
- * Copyright (C) 2019 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
+ * Copyright (C) 2019, 2021 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
* Author: Luis Carlos Cobo <luisca@cozybit.com>
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
#include <linux/gfp.h>
|
|
Takashi Iwai |
8eb966 |
@@ -1200,7 +1200,7 @@ void mesh_rx_plink_frame(struct ieee8021
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *mgmt, size_t len,
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_rx_status *rx_status)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
u8 *baseaddr;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -1228,7 +1228,8 @@ void mesh_rx_plink_frame(struct ieee8021
|
|
Takashi Iwai |
8eb966 |
if (baselen > len)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(baseaddr, len - baselen, true, &elems,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
- mesh_process_plink_frame(sdata, mgmt, &elems, rx_status);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(baseaddr, len - baselen, true,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ mesh_process_plink_frame(sdata, mgmt, elems, rx_status);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/mlme.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/mlme.c
|
|
Takashi Iwai |
8eb966 |
@@ -3312,8 +3312,11 @@ static bool ieee80211_assoc_success(stru
|
|
Takashi Iwai |
8eb966 |
aid = 0; /* TODO */
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, elems,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid, assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return false;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (elems->aid_resp)
|
|
Takashi Iwai |
8eb966 |
aid = le16_to_cpu(elems->aid_resp->aid);
|
|
Takashi Iwai |
8eb966 |
@@ -3335,7 +3338,8 @@ static bool ieee80211_assoc_success(stru
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (!is_s1g && !elems->supp_rates) {
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata, "no SuppRates element in AssocResp\n");
|
|
Takashi Iwai |
8eb966 |
- return false;
|
|
Takashi Iwai |
8eb966 |
+ ret = false;
|
|
Takashi Iwai |
8eb966 |
+ goto out;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
sdata->vif.bss_conf.aid = aid;
|
|
Takashi Iwai |
8eb966 |
@@ -3357,7 +3361,7 @@ static bool ieee80211_assoc_success(stru
|
|
Takashi Iwai |
8eb966 |
(!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT) &&
|
|
Takashi Iwai |
8eb966 |
(!elems->vht_cap_elem || !elems->vht_operation)))) {
|
|
Takashi Iwai |
8eb966 |
const struct cfg80211_bss_ies *ies;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems bss_elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *bss_elems;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
rcu_read_lock();
|
|
Takashi Iwai |
8eb966 |
ies = rcu_dereference(cbss->ies);
|
|
Takashi Iwai |
8eb966 |
@@ -3368,13 +3372,17 @@ static bool ieee80211_assoc_success(stru
|
|
Takashi Iwai |
8eb966 |
if (!bss_ies)
|
|
Takashi Iwai |
8eb966 |
return false;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
|
|
Takashi Iwai |
8eb966 |
- false, &bss_elems,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid,
|
|
Takashi Iwai |
8eb966 |
- assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
|
|
Takashi Iwai |
8eb966 |
+ false, mgmt->bssid,
|
|
Takashi Iwai |
8eb966 |
+ assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ if (!bss_elems) {
|
|
Takashi Iwai |
8eb966 |
+ ret = false;
|
|
Takashi Iwai |
8eb966 |
+ goto out;
|
|
Takashi Iwai |
8eb966 |
+ }
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
if (assoc_data->wmm &&
|
|
Takashi Iwai |
8eb966 |
- !elems->wmm_param && bss_elems.wmm_param) {
|
|
Takashi Iwai |
8eb966 |
- elems->wmm_param = bss_elems.wmm_param;
|
|
Takashi Iwai |
8eb966 |
+ !elems->wmm_param && bss_elems->wmm_param) {
|
|
Takashi Iwai |
8eb966 |
+ elems->wmm_param = bss_elems->wmm_param;
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"AP bug: WMM param missing from AssocResp\n");
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
@@ -3383,30 +3391,32 @@ static bool ieee80211_assoc_success(stru
|
|
Takashi Iwai |
8eb966 |
* Also check if we requested HT/VHT, otherwise the AP doesn't
|
|
Takashi Iwai |
8eb966 |
* have to include the IEs in the (re)association response.
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
- if (!elems->ht_cap_elem && bss_elems.ht_cap_elem &&
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->ht_cap_elem && bss_elems->ht_cap_elem &&
|
|
Takashi Iwai |
8eb966 |
!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
|
|
Takashi Iwai |
8eb966 |
- elems->ht_cap_elem = bss_elems.ht_cap_elem;
|
|
Takashi Iwai |
8eb966 |
+ elems->ht_cap_elem = bss_elems->ht_cap_elem;
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"AP bug: HT capability missing from AssocResp\n");
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- if (!elems->ht_operation && bss_elems.ht_operation &&
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->ht_operation && bss_elems->ht_operation &&
|
|
Takashi Iwai |
8eb966 |
!(ifmgd->flags & IEEE80211_STA_DISABLE_HT)) {
|
|
Takashi Iwai |
8eb966 |
- elems->ht_operation = bss_elems.ht_operation;
|
|
Takashi Iwai |
8eb966 |
+ elems->ht_operation = bss_elems->ht_operation;
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"AP bug: HT operation missing from AssocResp\n");
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- if (!elems->vht_cap_elem && bss_elems.vht_cap_elem &&
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->vht_cap_elem && bss_elems->vht_cap_elem &&
|
|
Takashi Iwai |
8eb966 |
!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
|
|
Takashi Iwai |
8eb966 |
- elems->vht_cap_elem = bss_elems.vht_cap_elem;
|
|
Takashi Iwai |
8eb966 |
+ elems->vht_cap_elem = bss_elems->vht_cap_elem;
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"AP bug: VHT capa missing from AssocResp\n");
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
- if (!elems->vht_operation && bss_elems.vht_operation &&
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->vht_operation && bss_elems->vht_operation &&
|
|
Takashi Iwai |
8eb966 |
!(ifmgd->flags & IEEE80211_STA_DISABLE_VHT)) {
|
|
Takashi Iwai |
8eb966 |
- elems->vht_operation = bss_elems.vht_operation;
|
|
Takashi Iwai |
8eb966 |
+ elems->vht_operation = bss_elems->vht_operation;
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"AP bug: VHT operation missing from AssocResp\n");
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ kfree(bss_elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/*
|
|
Takashi Iwai |
8eb966 |
@@ -3660,6 +3670,7 @@ static bool ieee80211_assoc_success(stru
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ret = true;
|
|
Takashi Iwai |
8eb966 |
out:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
kfree(bss_ies);
|
|
Takashi Iwai |
8eb966 |
return ret;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
@@ -3671,7 +3682,7 @@ static void ieee80211_rx_mgmt_assoc_resp
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgd_assoc_data *assoc_data = ifmgd->assoc_data;
|
|
Takashi Iwai |
8eb966 |
u16 capab_info, status_code, aid;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
int ac, uapsd_queues = -1;
|
|
Takashi Iwai |
8eb966 |
u8 *pos;
|
|
Takashi Iwai |
8eb966 |
bool reassoc;
|
|
Takashi Iwai |
8eb966 |
@@ -3728,14 +3739,16 @@ static void ieee80211_rx_mgmt_assoc_resp
|
|
Takashi Iwai |
8eb966 |
fils_decrypt_assoc_resp(sdata, (u8 *)mgmt, &len, assoc_data) < 0)
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid, assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ goto notify_driver;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY &&
|
|
Takashi Iwai |
8eb966 |
- elems.timeout_int &&
|
|
Takashi Iwai |
8eb966 |
- elems.timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
|
|
Takashi Iwai |
8eb966 |
+ elems->timeout_int &&
|
|
Takashi Iwai |
8eb966 |
+ elems->timeout_int->type == WLAN_TIMEOUT_ASSOC_COMEBACK) {
|
|
Takashi Iwai |
8eb966 |
u32 tu, ms;
|
|
Takashi Iwai |
8eb966 |
- tu = le32_to_cpu(elems.timeout_int->value);
|
|
Takashi Iwai |
8eb966 |
+ tu = le32_to_cpu(elems->timeout_int->value);
|
|
Takashi Iwai |
8eb966 |
ms = tu * 1024 / 1000;
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"%pM rejected association temporarily; comeback duration %u TU (%u ms)\n",
|
|
Takashi Iwai |
8eb966 |
@@ -3755,7 +3768,7 @@ static void ieee80211_rx_mgmt_assoc_resp
|
|
Takashi Iwai |
8eb966 |
event.u.mlme.reason = status_code;
|
|
Takashi Iwai |
8eb966 |
drv_event_callback(sdata->local, sdata, &event);
|
|
Takashi Iwai |
8eb966 |
} else {
|
|
Takashi Iwai |
8eb966 |
- if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, &elems)) {
|
|
Takashi Iwai |
8eb966 |
+ if (!ieee80211_assoc_success(sdata, cbss, mgmt, len, elems)) {
|
|
Takashi Iwai |
8eb966 |
/* oops -- internal error -- send timeout for now */
|
|
Takashi Iwai |
8eb966 |
ieee80211_destroy_assoc_data(sdata, false, false);
|
|
Takashi Iwai |
8eb966 |
cfg80211_assoc_timeout(sdata->dev, cbss);
|
|
Takashi Iwai |
8eb966 |
@@ -3785,6 +3798,7 @@ static void ieee80211_rx_mgmt_assoc_resp
|
|
Takashi Iwai |
8eb966 |
ifmgd->assoc_req_ies, ifmgd->assoc_req_ies_len);
|
|
Takashi Iwai |
8eb966 |
notify_driver:
|
|
Takashi Iwai |
8eb966 |
drv_mgd_complete_tx(sdata->local, sdata, &info;;
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
static void ieee80211_rx_bss_info(struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
8eb966 |
@@ -3989,7 +4003,7 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_bss_conf *bss_conf = &sdata->vif.bss_conf;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *mgmt = (void *) hdr;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_local *local = sdata->local;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_chanctx_conf *chanctx_conf;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_channel *chan;
|
|
Takashi Iwai |
8eb966 |
@@ -4035,15 +4049,16 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (ifmgd->assoc_data && ifmgd->assoc_data->need_beacon &&
|
|
Takashi Iwai |
8eb966 |
ieee80211_rx_our_beacon(bssid, ifmgd->assoc_data->bss)) {
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(variable,
|
|
Takashi Iwai |
8eb966 |
- len - baselen, false, &elems,
|
|
Takashi Iwai |
8eb966 |
- bssid,
|
|
Takashi Iwai |
8eb966 |
- ifmgd->assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(variable, len - baselen, false,
|
|
Takashi Iwai |
8eb966 |
+ bssid,
|
|
Takashi Iwai |
8eb966 |
+ ifmgd->assoc_data->bss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee80211_rx_bss_info(sdata, mgmt, len, rx_status);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.dtim_period)
|
|
Takashi Iwai |
8eb966 |
- ifmgd->dtim_period = elems.dtim_period;
|
|
Takashi Iwai |
8eb966 |
+ if (elems->dtim_period)
|
|
Takashi Iwai |
8eb966 |
+ ifmgd->dtim_period = elems->dtim_period;
|
|
Takashi Iwai |
8eb966 |
ifmgd->have_beacon = true;
|
|
Takashi Iwai |
8eb966 |
ifmgd->assoc_data->need_beacon = false;
|
|
Takashi Iwai |
8eb966 |
if (ieee80211_hw_check(&local->hw, TIMING_BEACON_ONLY)) {
|
|
Takashi Iwai |
8eb966 |
@@ -4051,17 +4066,17 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
le64_to_cpu(mgmt->u.beacon.timestamp);
|
|
Takashi Iwai |
8eb966 |
sdata->vif.bss_conf.sync_device_ts =
|
|
Takashi Iwai |
8eb966 |
rx_status->device_timestamp;
|
|
Takashi Iwai |
8eb966 |
- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count;
|
|
Takashi Iwai |
8eb966 |
+ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.mbssid_config_ie)
|
|
Takashi Iwai |
8eb966 |
+ if (elems->mbssid_config_ie)
|
|
Takashi Iwai |
8eb966 |
bss_conf->profile_periodicity =
|
|
Takashi Iwai |
8eb966 |
- elems.mbssid_config_ie->profile_periodicity;
|
|
Takashi Iwai |
8eb966 |
+ elems->mbssid_config_ie->profile_periodicity;
|
|
Takashi Iwai |
8eb966 |
else
|
|
Takashi Iwai |
8eb966 |
bss_conf->profile_periodicity = 0;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.ext_capab_len >= 11 &&
|
|
Takashi Iwai |
8eb966 |
- (elems.ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
|
|
Takashi Iwai |
8eb966 |
+ if (elems->ext_capab_len >= 11 &&
|
|
Takashi Iwai |
8eb966 |
+ (elems->ext_capab[10] & WLAN_EXT_CAPA11_EMA_SUPPORT))
|
|
Takashi Iwai |
8eb966 |
bss_conf->ema_ap = true;
|
|
Takashi Iwai |
8eb966 |
else
|
|
Takashi Iwai |
8eb966 |
bss_conf->ema_ap = false;
|
|
Takashi Iwai |
8eb966 |
@@ -4070,6 +4085,7 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
ifmgd->assoc_data->timeout = jiffies;
|
|
Takashi Iwai |
8eb966 |
ifmgd->assoc_data->timeout_started = true;
|
|
Takashi Iwai |
8eb966 |
run_again(sdata, ifmgd->assoc_data->timeout);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
return;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -4101,14 +4117,15 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
if (!ieee80211_is_s1g_beacon(hdr->frame_control))
|
|
Takashi Iwai |
8eb966 |
ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems_crc(variable,
|
|
Takashi Iwai |
8eb966 |
- len - baselen, false, &elems,
|
|
Takashi Iwai |
8eb966 |
- care_about_ies, ncrc,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid, bssid);
|
|
Takashi Iwai |
8eb966 |
- ncrc = elems.crc;
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems_crc(variable, len - baselen,
|
|
Takashi Iwai |
8eb966 |
+ false, care_about_ies, ncrc,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, bssid);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return;
|
|
Takashi Iwai |
8eb966 |
+ ncrc = elems->crc;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
|
|
Takashi Iwai |
8eb966 |
- ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) {
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_check_tim(elems->tim, elems->tim_len, bss_conf->aid)) {
|
|
Takashi Iwai |
8eb966 |
if (local->hw.conf.dynamic_ps_timeout > 0) {
|
|
Takashi Iwai |
8eb966 |
if (local->hw.conf.flags & IEEE80211_CONF_PS) {
|
|
Takashi Iwai |
8eb966 |
local->hw.conf.flags &= ~IEEE80211_CONF_PS;
|
|
Takashi Iwai |
8eb966 |
@@ -4178,12 +4195,12 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
le64_to_cpu(mgmt->u.beacon.timestamp);
|
|
Takashi Iwai |
8eb966 |
sdata->vif.bss_conf.sync_device_ts =
|
|
Takashi Iwai |
8eb966 |
rx_status->device_timestamp;
|
|
Takashi Iwai |
8eb966 |
- sdata->vif.bss_conf.sync_dtim_count = elems.dtim_count;
|
|
Takashi Iwai |
8eb966 |
+ sdata->vif.bss_conf.sync_dtim_count = elems->dtim_count;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if ((ncrc == ifmgd->beacon_crc && ifmgd->beacon_crc_valid) ||
|
|
Takashi Iwai |
8eb966 |
ieee80211_is_s1g_short_beacon(mgmt->frame_control))
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
ifmgd->beacon_crc = ncrc;
|
|
Takashi Iwai |
8eb966 |
ifmgd->beacon_crc_valid = true;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -4191,12 +4208,12 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee80211_sta_process_chanswitch(sdata, rx_status->mactime,
|
|
Takashi Iwai |
8eb966 |
rx_status->device_timestamp,
|
|
Takashi Iwai |
8eb966 |
- &elems, true);
|
|
Takashi Iwai |
8eb966 |
+ elems, true);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
if (!(ifmgd->flags & IEEE80211_STA_DISABLE_WMM) &&
|
|
Takashi Iwai |
8eb966 |
- ieee80211_sta_wmm_params(local, sdata, elems.wmm_param,
|
|
Takashi Iwai |
8eb966 |
- elems.wmm_param_len,
|
|
Takashi Iwai |
8eb966 |
- elems.mu_edca_param_set))
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_sta_wmm_params(local, sdata, elems->wmm_param,
|
|
Takashi Iwai |
8eb966 |
+ elems->wmm_param_len,
|
|
Takashi Iwai |
8eb966 |
+ elems->mu_edca_param_set))
|
|
Takashi Iwai |
8eb966 |
changed |= BSS_CHANGED_QOS;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/*
|
|
Takashi Iwai |
8eb966 |
@@ -4205,7 +4222,7 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
if (!ifmgd->have_beacon) {
|
|
Takashi Iwai |
8eb966 |
/* a few bogus AP send dtim_period = 0 or no TIM IE */
|
|
Takashi Iwai |
8eb966 |
- bss_conf->dtim_period = elems.dtim_period ?: 1;
|
|
Takashi Iwai |
8eb966 |
+ bss_conf->dtim_period = elems->dtim_period ?: 1;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
changed |= BSS_CHANGED_BEACON_INFO;
|
|
Takashi Iwai |
8eb966 |
ifmgd->have_beacon = true;
|
|
Takashi Iwai |
8eb966 |
@@ -4217,9 +4234,9 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
ieee80211_recalc_ps_vif(sdata);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.erp_info) {
|
|
Takashi Iwai |
8eb966 |
+ if (elems->erp_info) {
|
|
Takashi Iwai |
8eb966 |
erp_valid = true;
|
|
Takashi Iwai |
8eb966 |
- erp_value = elems.erp_info[0];
|
|
Takashi Iwai |
8eb966 |
+ erp_value = elems->erp_info[0];
|
|
Takashi Iwai |
8eb966 |
} else {
|
|
Takashi Iwai |
8eb966 |
erp_valid = false;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
@@ -4232,12 +4249,12 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
mutex_lock(&local->sta_mtx);
|
|
Takashi Iwai |
8eb966 |
sta = sta_info_get(sdata, bssid);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- changed |= ieee80211_recalc_twt_req(sdata, sta, &elems);
|
|
Takashi Iwai |
8eb966 |
+ changed |= ieee80211_recalc_twt_req(sdata, sta, elems);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (ieee80211_config_bw(sdata, sta, elems.ht_cap_elem,
|
|
Takashi Iwai |
8eb966 |
- elems.vht_cap_elem, elems.ht_operation,
|
|
Takashi Iwai |
8eb966 |
- elems.vht_operation, elems.he_operation,
|
|
Takashi Iwai |
8eb966 |
- elems.s1g_oper, bssid, &changed)) {
|
|
Takashi Iwai |
8eb966 |
+ if (ieee80211_config_bw(sdata, sta, elems->ht_cap_elem,
|
|
Takashi Iwai |
8eb966 |
+ elems->vht_cap_elem, elems->ht_operation,
|
|
Takashi Iwai |
8eb966 |
+ elems->vht_operation, elems->he_operation,
|
|
Takashi Iwai |
8eb966 |
+ elems->s1g_oper, bssid, &changed)) {
|
|
Takashi Iwai |
8eb966 |
mutex_unlock(&local->sta_mtx);
|
|
Takashi Iwai |
8eb966 |
sdata_info(sdata,
|
|
Takashi Iwai |
8eb966 |
"failed to follow AP %pM bandwidth change, disconnect\n",
|
|
Takashi Iwai |
8eb966 |
@@ -4249,21 +4266,23 @@ static void ieee80211_rx_mgmt_beacon(str
|
|
Takashi Iwai |
8eb966 |
sizeof(deauth_buf), true,
|
|
Takashi Iwai |
8eb966 |
WLAN_REASON_DEAUTH_LEAVING,
|
|
Takashi Iwai |
8eb966 |
false);
|
|
Takashi Iwai |
8eb966 |
- return;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (sta && elems.opmode_notif)
|
|
Takashi Iwai |
8eb966 |
- ieee80211_vht_handle_opmode(sdata, sta, *elems.opmode_notif,
|
|
Takashi Iwai |
8eb966 |
+ if (sta && elems->opmode_notif)
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_vht_handle_opmode(sdata, sta, *elems->opmode_notif,
|
|
Takashi Iwai |
8eb966 |
rx_status->band);
|
|
Takashi Iwai |
8eb966 |
mutex_unlock(&local->sta_mtx);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
changed |= ieee80211_handle_pwr_constr(sdata, chan, mgmt,
|
|
Takashi Iwai |
8eb966 |
- elems.country_elem,
|
|
Takashi Iwai |
8eb966 |
- elems.country_elem_len,
|
|
Takashi Iwai |
8eb966 |
- elems.pwr_constr_elem,
|
|
Takashi Iwai |
8eb966 |
- elems.cisco_dtpc_elem);
|
|
Takashi Iwai |
8eb966 |
+ elems->country_elem,
|
|
Takashi Iwai |
8eb966 |
+ elems->country_elem_len,
|
|
Takashi Iwai |
8eb966 |
+ elems->pwr_constr_elem,
|
|
Takashi Iwai |
8eb966 |
+ elems->cisco_dtpc_elem);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee80211_bss_info_change_notify(sdata, changed);
|
|
Takashi Iwai |
8eb966 |
+free:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
void ieee80211_sta_rx_queued_ext(struct ieee80211_sub_if_data *sdata,
|
|
Takashi Iwai |
8eb966 |
@@ -4292,7 +4311,6 @@ void ieee80211_sta_rx_queued_mgmt(struct
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_rx_status *rx_status;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_mgmt *mgmt;
|
|
Takashi Iwai |
8eb966 |
u16 fc;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
int ies_len;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
rx_status = (struct ieee80211_rx_status *) skb->cb;
|
|
Takashi Iwai |
8eb966 |
@@ -4324,6 +4342,8 @@ void ieee80211_sta_rx_queued_mgmt(struct
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
case IEEE80211_STYPE_ACTION:
|
|
Takashi Iwai |
8eb966 |
if (mgmt->u.action.category == WLAN_CATEGORY_SPECTRUM_MGMT) {
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
ies_len = skb->len -
|
|
Takashi Iwai |
8eb966 |
offsetof(struct ieee80211_mgmt,
|
|
Takashi Iwai |
8eb966 |
u.action.u.chan_switch.variable);
|
|
Takashi Iwai |
8eb966 |
@@ -4332,18 +4352,21 @@ void ieee80211_sta_rx_queued_mgmt(struct
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* CSA IE cannot be overridden, no need for BSSID */
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(
|
|
Takashi Iwai |
8eb966 |
- mgmt->u.action.u.chan_switch.variable,
|
|
Takashi Iwai |
8eb966 |
- ies_len, true, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(
|
|
Takashi Iwai |
8eb966 |
+ mgmt->u.action.u.chan_switch.variable,
|
|
Takashi Iwai |
8eb966 |
+ ies_len, true, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.parse_error)
|
|
Takashi Iwai |
8eb966 |
+ if (!elems || elems->parse_error)
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee80211_sta_process_chanswitch(sdata,
|
|
Takashi Iwai |
8eb966 |
rx_status->mactime,
|
|
Takashi Iwai |
8eb966 |
rx_status->device_timestamp,
|
|
Takashi Iwai |
8eb966 |
- &elems, false);
|
|
Takashi Iwai |
8eb966 |
+ elems, false);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
} else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
ies_len = skb->len -
|
|
Takashi Iwai |
8eb966 |
offsetof(struct ieee80211_mgmt,
|
|
Takashi Iwai |
8eb966 |
u.action.u.ext_chan_switch.variable);
|
|
Takashi Iwai |
8eb966 |
@@ -4355,21 +4378,22 @@ void ieee80211_sta_rx_queued_mgmt(struct
|
|
Takashi Iwai |
8eb966 |
* extended CSA IE can't be overridden, no need for
|
|
Takashi Iwai |
8eb966 |
* BSSID
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(
|
|
Takashi Iwai |
8eb966 |
- mgmt->u.action.u.ext_chan_switch.variable,
|
|
Takashi Iwai |
8eb966 |
- ies_len, true, &elems, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(
|
|
Takashi Iwai |
8eb966 |
+ mgmt->u.action.u.ext_chan_switch.variable,
|
|
Takashi Iwai |
8eb966 |
+ ies_len, true, mgmt->bssid, NULL);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (elems.parse_error)
|
|
Takashi Iwai |
8eb966 |
+ if (!elems || elems->parse_error)
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* for the handling code pretend this was also an IE */
|
|
Takashi Iwai |
8eb966 |
- elems.ext_chansw_ie =
|
|
Takashi Iwai |
8eb966 |
+ elems->ext_chansw_ie =
|
|
Takashi Iwai |
8eb966 |
&mgmt->u.action.u.ext_chan_switch.data;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
ieee80211_sta_process_chanswitch(sdata,
|
|
Takashi Iwai |
8eb966 |
rx_status->mactime,
|
|
Takashi Iwai |
8eb966 |
rx_status->device_timestamp,
|
|
Takashi Iwai |
8eb966 |
- &elems, false);
|
|
Takashi Iwai |
8eb966 |
+ elems, false);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/scan.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/scan.c
|
|
Takashi Iwai |
8eb966 |
@@ -9,7 +9,7 @@
|
|
Takashi Iwai |
8eb966 |
* Copyright 2007, Michael Wu <flamingice@sourmilk.net>
|
|
Takashi Iwai |
8eb966 |
* Copyright 2013-2015 Intel Mobile Communications GmbH
|
|
Takashi Iwai |
8eb966 |
* Copyright 2016-2017 Intel Deutschland GmbH
|
|
Takashi Iwai |
8eb966 |
- * Copyright (C) 2018-2020 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
+ * Copyright (C) 2018-2021 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
#include <linux/if_arp.h>
|
|
Takashi Iwai |
8eb966 |
@@ -155,7 +155,7 @@ ieee80211_bss_info_update(struct ieee802
|
|
Takashi Iwai |
8eb966 |
};
|
|
Takashi Iwai |
8eb966 |
bool signal_valid;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_sub_if_data *scan_sdata;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
size_t baselen;
|
|
Takashi Iwai |
8eb966 |
u8 *elements;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -209,8 +209,10 @@ ieee80211_bss_info_update(struct ieee802
|
|
Takashi Iwai |
8eb966 |
if (baselen > len)
|
|
Takashi Iwai |
8eb966 |
return NULL;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(elements, len - baselen, false, &elems,
|
|
Takashi Iwai |
8eb966 |
- mgmt->bssid, cbss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(elements, len - baselen, false,
|
|
Takashi Iwai |
8eb966 |
+ mgmt->bssid, cbss->bssid);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return NULL;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* In case the signal is invalid update the status */
|
|
Takashi Iwai |
8eb966 |
signal_valid = channel == cbss->channel;
|
|
Takashi Iwai |
8eb966 |
@@ -218,15 +220,17 @@ ieee80211_bss_info_update(struct ieee802
|
|
Takashi Iwai |
8eb966 |
rx_status->flag |= RX_FLAG_NO_SIGNAL_VAL;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
bss = (void *)cbss->priv;
|
|
Takashi Iwai |
8eb966 |
- ieee80211_update_bss_from_elems(local, bss, &elems, rx_status, beacon);
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_update_bss_from_elems(local, bss, elems, rx_status, beacon);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
list_for_each_entry(non_tx_cbss, &cbss->nontrans_list, nontrans_list) {
|
|
Takashi Iwai |
8eb966 |
non_tx_bss = (void *)non_tx_cbss->priv;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee80211_update_bss_from_elems(local, non_tx_bss, &elems,
|
|
Takashi Iwai |
8eb966 |
+ ieee80211_update_bss_from_elems(local, non_tx_bss, elems,
|
|
Takashi Iwai |
8eb966 |
rx_status, beacon);
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
return bss;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/tdls.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/tdls.c
|
|
Takashi Iwai |
8eb966 |
@@ -6,7 +6,7 @@
|
|
Takashi Iwai |
8eb966 |
* Copyright 2014, Intel Corporation
|
|
Takashi Iwai |
8eb966 |
* Copyright 2014 Intel Mobile Communications GmbH
|
|
Takashi Iwai |
8eb966 |
* Copyright 2015 - 2016 Intel Deutschland GmbH
|
|
Takashi Iwai |
8eb966 |
- * Copyright (C) 2019 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
+ * Copyright (C) 2019, 2021 Intel Corporation
|
|
Takashi Iwai |
8eb966 |
*/
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
#include <linux/ieee80211.h>
|
|
Takashi Iwai |
8eb966 |
@@ -1684,7 +1684,7 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
struct sk_buff *skb)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_local *local = sdata->local;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems = NULL;
|
|
Takashi Iwai |
8eb966 |
struct sta_info *sta;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_tdls_data *tf = (void *)skb->data;
|
|
Takashi Iwai |
8eb966 |
bool local_initiator;
|
|
Takashi Iwai |
8eb966 |
@@ -1718,16 +1718,20 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
goto call_drv;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(tf->u.chan_switch_resp.variable,
|
|
Takashi Iwai |
8eb966 |
- skb->len - baselen, false, &elems,
|
|
Takashi Iwai |
8eb966 |
- NULL, NULL);
|
|
Takashi Iwai |
8eb966 |
- if (elems.parse_error) {
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(tf->u.chan_switch_resp.variable,
|
|
Takashi Iwai |
8eb966 |
+ skb->len - baselen, false, NULL, NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems) {
|
|
Takashi Iwai |
8eb966 |
+ ret = -ENOMEM;
|
|
Takashi Iwai |
8eb966 |
+ goto out;
|
|
Takashi Iwai |
8eb966 |
+ }
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ if (elems->parse_error) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "Invalid IEs in TDLS channel switch resp\n");
|
|
Takashi Iwai |
8eb966 |
ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
goto out;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (!elems.ch_sw_timing || !elems.lnk_id) {
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->ch_sw_timing || !elems->lnk_id) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "TDLS channel switch resp - missing IEs\n");
|
|
Takashi Iwai |
8eb966 |
ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
goto out;
|
|
Takashi Iwai |
8eb966 |
@@ -1735,15 +1739,15 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* validate the initiator is set correctly */
|
|
Takashi Iwai |
8eb966 |
local_initiator =
|
|
Takashi Iwai |
8eb966 |
- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
|
|
Takashi Iwai |
8eb966 |
+ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
|
|
Takashi Iwai |
8eb966 |
if (local_initiator == sta->sta.tdls_initiator) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n");
|
|
Takashi Iwai |
8eb966 |
ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
goto out;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time);
|
|
Takashi Iwai |
8eb966 |
- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout);
|
|
Takashi Iwai |
8eb966 |
+ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time);
|
|
Takashi Iwai |
8eb966 |
+ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
params.tmpl_skb =
|
|
Takashi Iwai |
8eb966 |
ieee80211_tdls_ch_sw_resp_tmpl_get(sta, ¶ms.ch_sw_tm_ie);
|
|
Takashi Iwai |
8eb966 |
@@ -1763,6 +1767,7 @@ call_drv:
|
|
Takashi Iwai |
8eb966 |
out:
|
|
Takashi Iwai |
8eb966 |
mutex_unlock(&local->sta_mtx);
|
|
Takashi Iwai |
8eb966 |
dev_kfree_skb_any(params.tmpl_skb);
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
return ret;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -1771,7 +1776,7 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
struct sk_buff *skb)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_local *local = sdata->local;
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems elems;
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
struct cfg80211_chan_def chandef;
|
|
Takashi Iwai |
8eb966 |
struct ieee80211_channel *chan;
|
|
Takashi Iwai |
8eb966 |
enum nl80211_channel_type chan_type;
|
|
Takashi Iwai |
8eb966 |
@@ -1831,22 +1836,27 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
return -EINVAL;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- ieee802_11_parse_elems(tf->u.chan_switch_req.variable,
|
|
Takashi Iwai |
8eb966 |
- skb->len - baselen, false, &elems, NULL, NULL);
|
|
Takashi Iwai |
8eb966 |
- if (elems.parse_error) {
|
|
Takashi Iwai |
8eb966 |
+ elems = ieee802_11_parse_elems(tf->u.chan_switch_req.variable,
|
|
Takashi Iwai |
8eb966 |
+ skb->len - baselen, false, NULL, NULL);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return -ENOMEM;
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ if (elems->parse_error) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "Invalid IEs in TDLS channel switch req\n");
|
|
Takashi Iwai |
8eb966 |
- return -EINVAL;
|
|
Takashi Iwai |
8eb966 |
+ ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (!elems.ch_sw_timing || !elems.lnk_id) {
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->ch_sw_timing || !elems->lnk_id) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "TDLS channel switch req - missing IEs\n");
|
|
Takashi Iwai |
8eb966 |
- return -EINVAL;
|
|
Takashi Iwai |
8eb966 |
+ ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- if (!elems.sec_chan_offs) {
|
|
Takashi Iwai |
8eb966 |
+ if (!elems->sec_chan_offs) {
|
|
Takashi Iwai |
8eb966 |
chan_type = NL80211_CHAN_HT20;
|
|
Takashi Iwai |
8eb966 |
} else {
|
|
Takashi Iwai |
8eb966 |
- switch (elems.sec_chan_offs->sec_chan_offs) {
|
|
Takashi Iwai |
8eb966 |
+ switch (elems->sec_chan_offs->sec_chan_offs) {
|
|
Takashi Iwai |
8eb966 |
case IEEE80211_HT_PARAM_CHA_SEC_ABOVE:
|
|
Takashi Iwai |
8eb966 |
chan_type = NL80211_CHAN_HT40PLUS;
|
|
Takashi Iwai |
8eb966 |
break;
|
|
Takashi Iwai |
8eb966 |
@@ -1865,7 +1875,8 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
if (!cfg80211_reg_can_beacon_relax(sdata->local->hw.wiphy, &chandef,
|
|
Takashi Iwai |
8eb966 |
sdata->wdev.iftype)) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "TDLS chan switch to forbidden channel\n");
|
|
Takashi Iwai |
8eb966 |
- return -EINVAL;
|
|
Takashi Iwai |
8eb966 |
+ ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
+ goto free;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
mutex_lock(&local->sta_mtx);
|
|
Takashi Iwai |
8eb966 |
@@ -1881,7 +1892,7 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* validate the initiator is set correctly */
|
|
Takashi Iwai |
8eb966 |
local_initiator =
|
|
Takashi Iwai |
8eb966 |
- !memcmp(elems.lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
|
|
Takashi Iwai |
8eb966 |
+ !memcmp(elems->lnk_id->init_sta, sdata->vif.addr, ETH_ALEN);
|
|
Takashi Iwai |
8eb966 |
if (local_initiator == sta->sta.tdls_initiator) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "TDLS chan switch invalid lnk-id initiator\n");
|
|
Takashi Iwai |
8eb966 |
ret = -EINVAL;
|
|
Takashi Iwai |
8eb966 |
@@ -1889,16 +1900,16 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
/* peer should have known better */
|
|
Takashi Iwai |
8eb966 |
- if (!sta->sta.ht_cap.ht_supported && elems.sec_chan_offs &&
|
|
Takashi Iwai |
8eb966 |
- elems.sec_chan_offs->sec_chan_offs) {
|
|
Takashi Iwai |
8eb966 |
+ if (!sta->sta.ht_cap.ht_supported && elems->sec_chan_offs &&
|
|
Takashi Iwai |
8eb966 |
+ elems->sec_chan_offs->sec_chan_offs) {
|
|
Takashi Iwai |
8eb966 |
tdls_dbg(sdata, "TDLS chan switch - wide chan unsupported\n");
|
|
Takashi Iwai |
8eb966 |
ret = -ENOTSUPP;
|
|
Takashi Iwai |
8eb966 |
goto out;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
params.chandef = &chandef;
|
|
Takashi Iwai |
8eb966 |
- params.switch_time = le16_to_cpu(elems.ch_sw_timing->switch_time);
|
|
Takashi Iwai |
8eb966 |
- params.switch_timeout = le16_to_cpu(elems.ch_sw_timing->switch_timeout);
|
|
Takashi Iwai |
8eb966 |
+ params.switch_time = le16_to_cpu(elems->ch_sw_timing->switch_time);
|
|
Takashi Iwai |
8eb966 |
+ params.switch_timeout = le16_to_cpu(elems->ch_sw_timing->switch_timeout);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
params.tmpl_skb =
|
|
Takashi Iwai |
8eb966 |
ieee80211_tdls_ch_sw_resp_tmpl_get(sta,
|
|
Takashi Iwai |
8eb966 |
@@ -1917,6 +1928,8 @@ ieee80211_process_tdls_channel_switch_re
|
|
Takashi Iwai |
8eb966 |
out:
|
|
Takashi Iwai |
8eb966 |
mutex_unlock(&local->sta_mtx);
|
|
Takashi Iwai |
8eb966 |
dev_kfree_skb_any(params.tmpl_skb);
|
|
Takashi Iwai |
8eb966 |
+free:
|
|
Takashi Iwai |
8eb966 |
+ kfree(elems);
|
|
Takashi Iwai |
8eb966 |
return ret;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
--- a/net/mac80211/util.c
|
|
Takashi Iwai |
8eb966 |
+++ b/net/mac80211/util.c
|
|
Takashi Iwai |
8eb966 |
@@ -1384,8 +1384,8 @@ _ieee802_11_parse_elems_crc(const u8 *st
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
static size_t ieee802_11_find_bssid_profile(const u8 *start, size_t len,
|
|
Takashi Iwai |
8eb966 |
struct ieee802_11_elems *elems,
|
|
Takashi Iwai |
8eb966 |
- u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
- u8 *bss_bssid,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *bss_bssid,
|
|
Takashi Iwai |
8eb966 |
u8 *nontransmitted_profile)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
const struct element *elem, *sub;
|
|
Takashi Iwai |
8eb966 |
@@ -1452,16 +1452,20 @@ static size_t ieee802_11_find_bssid_prof
|
|
Takashi Iwai |
8eb966 |
return found ? profile_len : 0;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
-void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
|
|
Takashi Iwai |
8eb966 |
- struct ieee802_11_elems *elems,
|
|
Takashi Iwai |
8eb966 |
- u64 filter, u32 crc, u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
- u8 *bss_bssid)
|
|
Takashi Iwai |
8eb966 |
+struct ieee802_11_elems *ieee802_11_parse_elems_crc(const u8 *start, size_t len,
|
|
Takashi Iwai |
8eb966 |
+ bool action, u64 filter,
|
|
Takashi Iwai |
8eb966 |
+ u32 crc,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *transmitter_bssid,
|
|
Takashi Iwai |
8eb966 |
+ const u8 *bss_bssid)
|
|
Takashi Iwai |
8eb966 |
{
|
|
Takashi Iwai |
8eb966 |
+ struct ieee802_11_elems *elems;
|
|
Takashi Iwai |
8eb966 |
const struct element *non_inherit = NULL;
|
|
Takashi Iwai |
8eb966 |
u8 *nontransmitted_profile;
|
|
Takashi Iwai |
8eb966 |
int nontransmitted_profile_len = 0;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
- memset(elems, 0, sizeof(*elems));
|
|
Takashi Iwai |
8eb966 |
+ elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
|
|
Takashi Iwai |
8eb966 |
+ if (!elems)
|
|
Takashi Iwai |
8eb966 |
+ return NULL;
|
|
Takashi Iwai |
8eb966 |
elems->ie_start = start;
|
|
Takashi Iwai |
8eb966 |
elems->total_len = len;
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
@@ -1508,6 +1512,8 @@ void ieee802_11_parse_elems_crc(const u8
|
|
Takashi Iwai |
8eb966 |
kfree(nontransmitted_profile);
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
elems->crc = crc;
|
|
Takashi Iwai |
8eb966 |
+
|
|
Takashi Iwai |
8eb966 |
+ return elems;
|
|
Takashi Iwai |
8eb966 |
}
|
|
Takashi Iwai |
8eb966 |
|
|
Takashi Iwai |
8eb966 |
void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
|