mac80211: Update to version 5.15.74-1

This updates mac80211 to version 5.15.74-1 which is based on kernel
5.15.74.
The removed patches were applied upstream.

Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
This commit is contained in:
Hauke Mehrtens 2022-10-15 11:31:42 +02:00
parent 9f6cbc78cd
commit 58b65525f3
29 changed files with 36 additions and 2258 deletions

View File

@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=5.15.58-1
PKG_RELEASE:=2
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.58/
PKG_HASH:=a3c2a2b7bbaf8943c65fd72f4e7d7ad5e205aeae28b26c835f9d8afa0f9810bf
PKG_VERSION:=5.15.74-1
PKG_RELEASE:=1
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.15.74/
PKG_HASH:=98098d0cab24cc76a04db738dc746a0c8d38d180398805481224f141cca06423
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)

View File

@ -152,7 +152,7 @@ Signed-off-by: Pali Rohár <pali@kernel.org>
--- a/drivers/net/wireless/marvell/mwifiex/main.h
+++ b/drivers/net/wireless/marvell/mwifiex/main.h
@@ -1106,6 +1106,8 @@ void mwifiex_cancel_all_pending_cmd(stru
@@ -1108,6 +1108,8 @@ void mwifiex_cancel_all_pending_cmd(stru
void mwifiex_cancel_pending_scan_cmd(struct mwifiex_adapter *adapter);
void mwifiex_cancel_scan(struct mwifiex_adapter *adapter);

View File

@ -52,7 +52,7 @@ Signed-off-by: Xing Song <xing.song@mediatek.com>
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -2948,6 +2948,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
@@ -2950,6 +2950,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80
if (!fwd_skb)
goto out;

View File

@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3004,15 +3004,19 @@ static void mac80211_hwsim_he_capab(stru
@@ -3003,15 +3003,19 @@ static void mac80211_hwsim_he_capab(stru
{
u16 n_iftype_data;
@ -34,7 +34,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
return;
}
@@ -3302,6 +3306,12 @@ static int mac80211_hwsim_new_radio(stru
@@ -3301,6 +3305,12 @@ static int mac80211_hwsim_new_radio(stru
sband->vht_cap.vht_mcs.tx_mcs_map =
sband->vht_cap.vht_mcs.rx_mcs_map;
break;
@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
case NL80211_BAND_S1GHZ:
memcpy(&sband->s1g_cap, &hwsim_s1g_cap,
sizeof(sband->s1g_cap));
@@ -3312,6 +3322,13 @@ static int mac80211_hwsim_new_radio(stru
@@ -3311,6 +3321,13 @@ static int mac80211_hwsim_new_radio(stru
continue;
}
@ -61,7 +61,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
sband->ht_cap.ht_supported = true;
sband->ht_cap.cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
IEEE80211_HT_CAP_GRN_FLD |
@@ -3325,10 +3342,6 @@ static int mac80211_hwsim_new_radio(stru
@@ -3324,10 +3341,6 @@ static int mac80211_hwsim_new_radio(stru
sband->ht_cap.mcs.rx_mask[0] = 0xff;
sband->ht_cap.mcs.rx_mask[1] = 0xff;
sband->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;

View File

@ -69,7 +69,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
#endif /* __MAC80211_DRIVER_OPS */
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1490,7 +1490,7 @@ struct ieee80211_local {
@@ -1489,7 +1489,7 @@ struct ieee80211_local {
};
static inline struct ieee80211_sub_if_data *

View File

@ -246,7 +246,7 @@ Signed-off-by: Johannes Berg <johannes.berg@intel.com>
struct rcu_head rcu_head;
};
@@ -1083,6 +1084,20 @@ ieee80211_vif_get_shift(struct ieee80211
@@ -1082,6 +1083,20 @@ ieee80211_vif_get_shift(struct ieee80211
return shift;
}

View File

@ -327,7 +327,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -863,16 +863,20 @@ enum txq_info_flags {
@@ -862,16 +862,20 @@ enum txq_info_flags {
* @def_flow: used as a fallback flow when a packet destined to @tin hashes to
* a fq_flow which is already owned by a different tin
* @def_cvars: codel vars for @def_flow
@ -350,7 +350,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
unsigned long flags;
/* keep last! */
@@ -949,8 +953,6 @@ struct ieee80211_sub_if_data {
@@ -948,8 +952,6 @@ struct ieee80211_sub_if_data {
struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
struct mac80211_qos_map __rcu *qos_map;
@ -359,7 +359,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
struct work_struct csa_finalize_work;
bool csa_block_tx; /* write-protected by sdata_lock and local->mtx */
struct cfg80211_chan_def csa_chandef;
@@ -1185,44 +1187,6 @@ enum mac80211_scan_state {
@@ -1184,44 +1186,6 @@ enum mac80211_scan_state {
SCAN_ABORT,
};
@ -404,7 +404,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
DECLARE_STATIC_KEY_FALSE(aql_disable);
struct ieee80211_local {
@@ -1236,8 +1200,13 @@ struct ieee80211_local {
@@ -1235,8 +1199,13 @@ struct ieee80211_local {
struct codel_params cparams;
/* protects active_txqs and txqi->schedule_order */
@ -419,7 +419,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
u32 aql_threshold;
atomic_t aql_total_pending_airtime;
@@ -1654,125 +1623,6 @@ static inline bool txq_has_queue(struct
@@ -1660,125 +1629,6 @@ static inline bool txq_has_queue(struct
return !(skb_queue_empty(&txqi->frags) && !txqi->tin.backlog_packets);
}
@ -545,7 +545,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
static inline int ieee80211_bssid_match(const u8 *raddr, const u8 *addr)
{
return ether_addr_equal(raddr, addr) ||
@@ -2018,14 +1868,6 @@ int ieee80211_tx_control_port(struct wip
@@ -2024,14 +1874,6 @@ int ieee80211_tx_control_port(struct wip
u64 *cookie);
int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev,
const u8 *buf, size_t len);

View File

@ -15,7 +15,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1216,6 +1216,7 @@ struct ieee80211_local {
@@ -1215,6 +1215,7 @@ struct ieee80211_local {
u32 aql_txq_limit_high[IEEE80211_NUM_ACS];
u32 aql_threshold;
atomic_t aql_total_pending_airtime;

View File

@ -13,7 +13,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4265,6 +4265,7 @@ void ieee80211_check_fast_rx(struct sta_
@@ -4267,6 +4267,7 @@ void ieee80211_check_fast_rx(struct sta_
.vif_type = sdata->vif.type,
.control_port_protocol = sdata->control_port_protocol,
}, *old, *new = NULL;
@ -21,7 +21,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
bool set_offload = false;
bool assign = false;
bool offload;
@@ -4380,10 +4381,10 @@ void ieee80211_check_fast_rx(struct sta_
@@ -4382,10 +4383,10 @@ void ieee80211_check_fast_rx(struct sta_
if (assign)
new = kmemdup(&fastrx, sizeof(fastrx), GFP_KERNEL);

View File

@ -14,7 +14,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -4601,7 +4601,7 @@ static bool ieee80211_invoke_fast_rx(str
@@ -4603,7 +4603,7 @@ static bool ieee80211_invoke_fast_rx(str
if (!(status->rx_flags & IEEE80211_RX_AMSDU)) {
if (!pskb_may_pull(skb, snap_offs + sizeof(*payload)))

View File

@ -1,110 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Mon, 20 Sep 2021 15:40:07 +0200
Subject: [PATCH] mac80211: mesh: clean up rx_bcn_presp API
commit a5b983c6073140b624f64e79fea6d33c3e4315a0 upstream.
We currently pass the entire elements to the rx_bcn_presp()
method, but only need mesh_config. Additionally, we use the
length of the elements to calculate back the entire frame's
length, but that's confusing - just pass the length of the
frame instead.
Link: https://lore.kernel.org/r/20210920154009.a18ed3d2da6c.I1824b773a0fbae4453e1433c184678ca14e8df45@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -645,10 +645,9 @@ struct ieee80211_if_ocb {
*/
struct ieee802_11_elems;
struct ieee80211_mesh_sync_ops {
- void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata,
- u16 stype,
- struct ieee80211_mgmt *mgmt,
- struct ieee802_11_elems *elems,
+ void (*rx_bcn_presp)(struct ieee80211_sub_if_data *sdata, u16 stype,
+ struct ieee80211_mgmt *mgmt, unsigned int len,
+ const struct ieee80211_meshconf_ie *mesh_cfg,
struct ieee80211_rx_status *rx_status);
/* should be called with beacon_data under RCU read lock */
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -1354,8 +1354,8 @@ static void ieee80211_mesh_rx_bcn_presp(
}
if (ifmsh->sync_ops)
- ifmsh->sync_ops->rx_bcn_presp(sdata,
- stype, mgmt, &elems, rx_status);
+ ifmsh->sync_ops->rx_bcn_presp(sdata, stype, mgmt, len,
+ elems.mesh_config, rx_status);
}
int ieee80211_mesh_finish_csa(struct ieee80211_sub_if_data *sdata)
--- a/net/mac80211/mesh_sync.c
+++ b/net/mac80211/mesh_sync.c
@@ -3,6 +3,7 @@
* Copyright 2011-2012, Pavel Zubarev <pavel.zubarev@gmail.com>
* Copyright 2011-2012, Marco Porsch <marco.porsch@s2005.tu-chemnitz.de>
* Copyright 2011-2012, cozybit Inc.
+ * Copyright (C) 2021 Intel Corporation
*/
#include "ieee80211_i.h"
@@ -35,12 +36,12 @@ struct sync_method {
/**
* mesh_peer_tbtt_adjusting - check if an mp is currently adjusting its TBTT
*
- * @ie: information elements of a management frame from the mesh peer
+ * @cfg: mesh config element from the mesh peer (or %NULL)
*/
-static bool mesh_peer_tbtt_adjusting(struct ieee802_11_elems *ie)
+static bool mesh_peer_tbtt_adjusting(const struct ieee80211_meshconf_ie *cfg)
{
- return (ie->mesh_config->meshconf_cap &
- IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING) != 0;
+ return cfg &&
+ (cfg->meshconf_cap & IEEE80211_MESHCONF_CAPAB_TBTT_ADJUSTING);
}
void mesh_sync_adjust_tsf(struct ieee80211_sub_if_data *sdata)
@@ -76,11 +77,11 @@ void mesh_sync_adjust_tsf(struct ieee802
}
}
-static void mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata,
- u16 stype,
- struct ieee80211_mgmt *mgmt,
- struct ieee802_11_elems *elems,
- struct ieee80211_rx_status *rx_status)
+static void
+mesh_sync_offset_rx_bcn_presp(struct ieee80211_sub_if_data *sdata, u16 stype,
+ struct ieee80211_mgmt *mgmt, unsigned int len,
+ const struct ieee80211_meshconf_ie *mesh_cfg,
+ struct ieee80211_rx_status *rx_status)
{
struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh;
struct ieee80211_local *local = sdata->local;
@@ -101,10 +102,7 @@ static void mesh_sync_offset_rx_bcn_pres
*/
if (ieee80211_have_rx_timestamp(rx_status))
t_r = ieee80211_calculate_rx_timestamp(local, rx_status,
- 24 + 12 +
- elems->total_len +
- FCS_LEN,
- 24);
+ len + FCS_LEN, 24);
else
t_r = drv_get_tsf(local, sdata);
@@ -119,7 +117,7 @@ static void mesh_sync_offset_rx_bcn_pres
* dot11MeshNbrOffsetMaxNeighbor non-peer non-MBSS neighbors
*/
- if (elems->mesh_config && mesh_peer_tbtt_adjusting(elems)) {
+ if (mesh_peer_tbtt_adjusting(mesh_cfg)) {
msync_dbg(sdata, "STA %pM : is adjusting TBTT\n",
sta->sta.addr);
goto no_sync;

View File

@ -1,82 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Mon, 20 Sep 2021 15:40:08 +0200
Subject: [PATCH] mac80211: move CRC into struct ieee802_11_elems
commit c6e37ed498f958254b5459253199e816b6bfc52f upstream.
We're currently returning this value, but to prepare for
returning the allocated structure, move it into there.
Link: https://lore.kernel.org/r/20210920154009.479b8ebf999d.If0d4ba75ee38998dc3eeae25058aa748efcb2fc9@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1530,6 +1530,7 @@ struct ieee80211_csa_ie {
struct ieee802_11_elems {
const u8 *ie_start;
size_t total_len;
+ u32 crc;
/* pointers to IEs */
const struct ieee80211_tdls_lnkie *lnk_id;
@@ -2089,10 +2090,10 @@ static inline void ieee80211_tx_skb(stru
ieee80211_tx_skb_tid(sdata, skb, 7);
}
-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
- struct ieee802_11_elems *elems,
- u64 filter, u32 crc, u8 *transmitter_bssid,
- u8 *bss_bssid);
+void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
+ struct ieee802_11_elems *elems,
+ u64 filter, u32 crc, u8 *transmitter_bssid,
+ u8 *bss_bssid);
static inline void ieee802_11_parse_elems(const u8 *start, size_t len,
bool action,
struct ieee802_11_elems *elems,
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4102,10 +4102,11 @@ static void ieee80211_rx_mgmt_beacon(str
*/
if (!ieee80211_is_s1g_beacon(hdr->frame_control))
ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
- ncrc = ieee802_11_parse_elems_crc(variable,
- len - baselen, false, &elems,
- care_about_ies, ncrc,
- mgmt->bssid, bssid);
+ ieee802_11_parse_elems_crc(variable,
+ len - baselen, false, &elems,
+ care_about_ies, ncrc,
+ mgmt->bssid, bssid);
+ ncrc = elems.crc;
if (ieee80211_hw_check(&local->hw, PS_NULLFUNC_STACK) &&
ieee80211_check_tim(elems.tim, elems.tim_len, bss_conf->aid)) {
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1469,10 +1469,10 @@ static size_t ieee802_11_find_bssid_prof
return found ? profile_len : 0;
}
-u32 ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
- struct ieee802_11_elems *elems,
- u64 filter, u32 crc, u8 *transmitter_bssid,
- u8 *bss_bssid)
+void ieee802_11_parse_elems_crc(const u8 *start, size_t len, bool action,
+ struct ieee802_11_elems *elems,
+ u64 filter, u32 crc, u8 *transmitter_bssid,
+ u8 *bss_bssid)
{
const struct element *non_inherit = NULL;
u8 *nontransmitted_profile;
@@ -1524,7 +1524,7 @@ u32 ieee802_11_parse_elems_crc(const u8
kfree(nontransmitted_profile);
- return crc;
+ elems->crc = crc;
}
void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,

View File

@ -1,80 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Mon, 20 Sep 2021 15:40:09 +0200
Subject: [PATCH] mac80211: mlme: find auth challenge directly
commit 49a765d6785e99157ff5091cc37485732496864e upstream.
There's no need to parse all elements etc. just to find the
authentication challenge - use cfg80211_find_elem() instead.
This also allows us to remove WLAN_EID_CHALLENGE handling
from the element parsing entirely.
Link: https://lore.kernel.org/r/20210920154009.45f9b3a15722.Ice3159ffad03a007d6154cbf1fb3a8c48489e86f@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1540,7 +1540,6 @@ struct ieee802_11_elems {
const u8 *supp_rates;
const u8 *ds_params;
const struct ieee80211_tim_ie *tim;
- const u8 *challenge;
const u8 *rsn;
const u8 *rsnx;
const u8 *erp_info;
@@ -1594,7 +1593,6 @@ struct ieee802_11_elems {
u8 ssid_len;
u8 supp_rates_len;
u8 tim_len;
- u8 challenge_len;
u8 rsn_len;
u8 rsnx_len;
u8 ext_supp_rates_len;
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2889,17 +2889,17 @@ static void ieee80211_auth_challenge(str
{
struct ieee80211_local *local = sdata->local;
struct ieee80211_mgd_auth_data *auth_data = sdata->u.mgd.auth_data;
+ const struct element *challenge;
u8 *pos;
- struct ieee802_11_elems elems;
u32 tx_flags = 0;
struct ieee80211_prep_tx_info info = {
.subtype = IEEE80211_STYPE_AUTH,
};
pos = mgmt->u.auth.variable;
- ieee802_11_parse_elems(pos, len - (pos - (u8 *)mgmt), false, &elems,
- mgmt->bssid, auth_data->bss->bssid);
- if (!elems.challenge)
+ challenge = cfg80211_find_elem(WLAN_EID_CHALLENGE, pos,
+ len - (pos - (u8 *)mgmt));
+ if (!challenge)
return;
auth_data->expected_transaction = 4;
drv_mgd_prepare_tx(sdata->local, sdata, &info);
@@ -2907,7 +2907,8 @@ static void ieee80211_auth_challenge(str
tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS |
IEEE80211_TX_INTFL_MLME_CONN_TX;
ieee80211_send_auth(sdata, 3, auth_data->algorithm, 0,
- elems.challenge - 2, elems.challenge_len + 2,
+ (void *)challenge,
+ challenge->datalen + sizeof(*challenge),
auth_data->bss->bssid, auth_data->bss->bssid,
auth_data->key, auth_data->key_len,
auth_data->key_idx, tx_flags);
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1120,10 +1120,6 @@ _ieee802_11_parse_elems_crc(const u8 *st
} else
elem_parse_failed = true;
break;
- case WLAN_EID_CHALLENGE:
- elems->challenge = pos;
- elems->challenge_len = elen;
- break;
case WLAN_EID_VENDOR_SPECIFIC:
if (elen >= 4 && pos[0] == 0x00 && pos[1] == 0x50 &&
pos[2] == 0xf2) {

View File

@ -1,115 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Fri, 1 Oct 2021 21:11:08 +0200
Subject: [PATCH] mac80211: fix memory leaks with element parsing
commit 8223ac199a3849257e86ec27865dc63f034b1cf1 upstream.
My previous commit 5d24828d05f3 ("mac80211: always allocate
struct ieee802_11_elems") had a few bugs and leaked the new
allocated struct in a few error cases, fix that.
Fixes: 5d24828d05f3 ("mac80211: always allocate struct ieee802_11_elems")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Link: https://lore.kernel.org/r/20211001211108.9839928e42e0.Ib81ca187d3d3af7ed1bfeac2e00d08a4637c8025@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -499,13 +499,14 @@ void ieee80211_process_addba_request(str
elems = ieee802_11_parse_elems(mgmt->u.action.u.addba_req.variable,
ies_len, true, mgmt->bssid, NULL);
if (!elems || elems->parse_error)
- return;
+ goto free;
}
__ieee80211_start_rx_ba_session(sta, dialog_token, timeout,
start_seq_num, ba_policy, tid,
buf_size, true, false,
elems ? elems->addba_ext_ie : NULL);
+free:
kfree(elems);
}
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1659,11 +1659,11 @@ void ieee80211_ibss_rx_queued_mgmt(struc
mgmt->u.action.u.chan_switch.variable,
ies_len, true, mgmt->bssid, NULL);
- if (!elems || elems->parse_error)
- break;
-
- ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt, skb->len,
- rx_status, elems);
+ if (elems && !elems->parse_error)
+ ieee80211_rx_mgmt_spectrum_mgmt(sdata, mgmt,
+ skb->len,
+ rx_status,
+ elems);
kfree(elems);
break;
}
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3374,8 +3374,10 @@ static bool ieee80211_assoc_success(stru
bss_ies = kmemdup(ies, sizeof(*ies) + ies->len,
GFP_ATOMIC);
rcu_read_unlock();
- if (!bss_ies)
- return false;
+ if (!bss_ies) {
+ ret = false;
+ goto out;
+ }
bss_elems = ieee802_11_parse_elems(bss_ies->data, bss_ies->len,
false, mgmt->bssid,
@@ -4358,13 +4360,11 @@ void ieee80211_sta_rx_queued_mgmt(struct
mgmt->u.action.u.chan_switch.variable,
ies_len, true, mgmt->bssid, NULL);
- if (!elems || elems->parse_error)
- break;
-
- ieee80211_sta_process_chanswitch(sdata,
- rx_status->mactime,
- rx_status->device_timestamp,
- elems, false);
+ if (elems && !elems->parse_error)
+ ieee80211_sta_process_chanswitch(sdata,
+ rx_status->mactime,
+ rx_status->device_timestamp,
+ elems, false);
kfree(elems);
} else if (mgmt->u.action.category == WLAN_CATEGORY_PUBLIC) {
struct ieee802_11_elems *elems;
@@ -4384,17 +4384,17 @@ void ieee80211_sta_rx_queued_mgmt(struct
mgmt->u.action.u.ext_chan_switch.variable,
ies_len, true, mgmt->bssid, NULL);
- if (!elems || elems->parse_error)
- break;
+ if (elems && !elems->parse_error) {
+ /* for the handling code pretend it was an IE */
+ elems->ext_chansw_ie =
+ &mgmt->u.action.u.ext_chan_switch.data;
+
+ ieee80211_sta_process_chanswitch(sdata,
+ rx_status->mactime,
+ rx_status->device_timestamp,
+ elems, false);
+ }
- /* for the handling code pretend this was also an IE */
- elems->ext_chansw_ie =
- &mgmt->u.action.u.ext_chan_switch.data;
-
- ieee80211_sta_process_chanswitch(sdata,
- rx_status->mactime,
- rx_status->device_timestamp,
- elems, false);
kfree(elems);
}
break;

View File

@ -1,41 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 28 Sep 2022 21:56:15 +0200
Subject: [PATCH] wifi: cfg80211: fix u8 overflow in
cfg80211_update_notlisted_nontrans()
commit aebe9f4639b13a1f4e9a6b42cdd2e38c617b442d upstream.
In the copy code of the elements, we do the following calculation
to reach the end of the MBSSID element:
/* copy the IEs after MBSSID */
cpy_len = mbssid[1] + 2;
This looks fine, however, cpy_len is a u8, the same as mbssid[1],
so the addition of two can overflow. In this case the subsequent
memcpy() will overflow the allocated buffer, since it copies 256
bytes too much due to the way the allocation and memcpy() sizes
are calculated.
Fix this by using size_t for the cpy_len variable.
This fixes CVE-2022-41674.
Reported-by: Soenke Huster <shuster@seemoo.tu-darmstadt.de>
Tested-by: Soenke Huster <shuster@seemoo.tu-darmstadt.de>
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -2238,7 +2238,7 @@ cfg80211_update_notlisted_nontrans(struc
size_t new_ie_len;
struct cfg80211_bss_ies *new_ies;
const struct cfg80211_bss_ies *old;
- u8 cpy_len;
+ size_t cpy_len;
lockdep_assert_held(&wiphy_to_rdev(wiphy)->bss_lock);

View File

@ -1,47 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 28 Sep 2022 22:01:37 +0200
Subject: [PATCH] wifi: cfg80211/mac80211: reject bad MBSSID elements
commit 8f033d2becc24aa6bfd2a5c104407963560caabc upstream
Per spec, the maximum value for the MaxBSSID ('n') indicator is 8,
and the minimum is 1 since a multiple BSSID set with just one BSSID
doesn't make sense (the # of BSSIDs is limited by 2^n).
Limit this in the parsing in both cfg80211 and mac80211, rejecting
any elements with an invalid value.
This fixes potentially bad shifts in the processing of these inside
the cfg80211_gen_new_bssid() function later.
I found this during the investigation of CVE-2022-41674 fixed by the
previous patch.
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
Fixes: 78ac51f81532 ("mac80211: support multi-bssid")
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1413,6 +1413,8 @@ static size_t ieee802_11_find_bssid_prof
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, start, len) {
if (elem->datalen < 2)
continue;
+ if (elem->data[0] < 1 || elem->data[0] > 8)
+ continue;
for_each_element(sub, elem->data + 1, elem->datalen - 1) {
u8 new_bssid[ETH_ALEN];
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -2103,6 +2103,8 @@ static void cfg80211_parse_mbssid_data(s
for_each_element_id(elem, WLAN_EID_MULTIPLE_BSSID, ie, ielen) {
if (elem->datalen < 4)
continue;
+ if (elem->data[0] < 1 || (int)elem->data[0] > 8)
+ continue;
for_each_element(sub, elem->data + 1, elem->datalen - 1) {
u8 profile_len;

View File

@ -1,94 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 28 Sep 2022 22:07:15 +0200
Subject: [PATCH] wifi: mac80211: fix MBSSID parsing use-after-free
commit ff05d4b45dd89b922578dac497dcabf57cf771c6
When we parse a multi-BSSID element, we might point some
element pointers into the allocated nontransmitted_profile.
However, we free this before returning, causing UAF when the
relevant pointers in the parsed elements are accessed.
Fix this by not allocating the scratch buffer separately but
as part of the returned structure instead, that way, there
are no lifetime issues with it.
The scratch buffer introduction as part of the returned data
here is taken from MLO feature work done by Ilan.
This fixes CVE-2022-42719.
Fixes: 5023b14cf4df ("mac80211: support profile split between elements")
Co-developed-by: Ilan Peer <ilan.peer@intel.com>
Signed-off-by: Ilan Peer <ilan.peer@intel.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1611,6 +1611,14 @@ struct ieee802_11_elems {
/* whether a parse error occurred while retrieving these elements */
bool parse_error;
+
+ /*
+ * scratch buffer that can be used for various element parsing related
+ * tasks, e.g., element de-fragmentation etc.
+ */
+ size_t scratch_len;
+ u8 *scratch_pos;
+ u8 scratch[];
};
static inline struct ieee80211_local *hw_to_local(
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1478,24 +1478,25 @@ struct ieee802_11_elems *ieee802_11_pars
u8 *nontransmitted_profile;
int nontransmitted_profile_len = 0;
- elems = kzalloc(sizeof(*elems), GFP_ATOMIC);
+ elems = kzalloc(sizeof(*elems) + len, GFP_ATOMIC);
if (!elems)
return NULL;
elems->ie_start = start;
elems->total_len = len;
- nontransmitted_profile = kmalloc(len, GFP_ATOMIC);
- if (nontransmitted_profile) {
- nontransmitted_profile_len =
- ieee802_11_find_bssid_profile(start, len, elems,
- transmitter_bssid,
- bss_bssid,
- nontransmitted_profile);
- non_inherit =
- cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
- nontransmitted_profile,
- nontransmitted_profile_len);
- }
+ elems->scratch_len = len;
+ elems->scratch_pos = elems->scratch;
+
+ nontransmitted_profile = elems->scratch_pos;
+ nontransmitted_profile_len =
+ ieee802_11_find_bssid_profile(start, len, elems,
+ transmitter_bssid,
+ bss_bssid,
+ nontransmitted_profile);
+ non_inherit =
+ cfg80211_find_ext_elem(WLAN_EID_EXT_NON_INHERITANCE,
+ nontransmitted_profile,
+ nontransmitted_profile_len);
crc = _ieee802_11_parse_elems_crc(start, len, action, elems, filter,
crc, non_inherit);
@@ -1524,8 +1525,6 @@ struct ieee802_11_elems *ieee802_11_pars
offsetofend(struct ieee80211_bssid_index, dtim_count))
elems->dtim_count = elems->bssid_index->dtim_count;
- kfree(nontransmitted_profile);
-
elems->crc = crc;
return elems;

View File

@ -1,41 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Thu, 29 Sep 2022 21:50:44 +0200
Subject: [PATCH] wifi: cfg80211: ensure length byte is present before
access
commit 567e14e39e8f8c6997a1378bc3be615afca86063 upstream.
When iterating the elements here, ensure the length byte is
present before checking it to see if the entire element will
fit into the buffer.
Longer term, we should rewrite this code using the type-safe
element iteration macros that check all of this.
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
Reported-by: Soenke Huster <shuster@seemoo.tu-darmstadt.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -304,7 +304,8 @@ static size_t cfg80211_gen_new_ie(const
tmp_old = cfg80211_find_ie(WLAN_EID_SSID, ie, ielen);
tmp_old = (tmp_old) ? tmp_old + tmp_old[1] + 2 : ie;
- while (tmp_old + tmp_old[1] + 2 - ie <= ielen) {
+ while (tmp_old + 2 - ie <= ielen &&
+ tmp_old + tmp_old[1] + 2 - ie <= ielen) {
if (tmp_old[0] == 0) {
tmp_old++;
continue;
@@ -364,7 +365,8 @@ static size_t cfg80211_gen_new_ie(const
* copied to new ie, skip ssid, capability, bssid-index ie
*/
tmp_new = sub_copy;
- while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
+ while (tmp_new + 2 - sub_copy <= subie_len &&
+ tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
tmp_new[0] == WLAN_EID_SSID)) {
memcpy(pos, tmp_new, tmp_new[1] + 2);

View File

@ -1,87 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Fri, 30 Sep 2022 23:44:23 +0200
Subject: [PATCH] wifi: cfg80211: fix BSS refcounting bugs
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 0b7808818cb9df6680f98996b8e9a439fa7bcc2f upstream.
There are multiple refcounting bugs related to multi-BSSID:
- In bss_ref_get(), if the BSS has a hidden_beacon_bss, then
the bss pointer is overwritten before checking for the
transmitted BSS, which is clearly wrong. Fix this by using
the bss_from_pub() macro.
- In cfg80211_bss_update() we copy the transmitted_bss pointer
from tmp into new, but then if we release new, we'll unref
it erroneously. We already set the pointer and ref it, but
need to NULL it since it was copied from the tmp data.
- In cfg80211_inform_single_bss_data(), if adding to the non-
transmitted list fails, we unlink the BSS and yet still we
return it, but this results in returning an entry without
a reference. We shouldn't return it anyway if it was broken
enough to not get added there.
This fixes CVE-2022-42720.
Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Fixes: a3584f56de1c ("cfg80211: Properly track transmitting and non-transmitting BSS")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -143,18 +143,12 @@ static inline void bss_ref_get(struct cf
lockdep_assert_held(&rdev->bss_lock);
bss->refcount++;
- if (bss->pub.hidden_beacon_bss) {
- bss = container_of(bss->pub.hidden_beacon_bss,
- struct cfg80211_internal_bss,
- pub);
- bss->refcount++;
- }
- if (bss->pub.transmitted_bss) {
- bss = container_of(bss->pub.transmitted_bss,
- struct cfg80211_internal_bss,
- pub);
- bss->refcount++;
- }
+
+ if (bss->pub.hidden_beacon_bss)
+ bss_from_pub(bss->pub.hidden_beacon_bss)->refcount++;
+
+ if (bss->pub.transmitted_bss)
+ bss_from_pub(bss->pub.transmitted_bss)->refcount++;
}
static inline void bss_ref_put(struct cfg80211_registered_device *rdev,
@@ -1743,6 +1737,8 @@ cfg80211_bss_update(struct cfg80211_regi
new->refcount = 1;
INIT_LIST_HEAD(&new->hidden_list);
INIT_LIST_HEAD(&new->pub.nontrans_list);
+ /* we'll set this later if it was non-NULL */
+ new->pub.transmitted_bss = NULL;
if (rcu_access_pointer(tmp->pub.proberesp_ies)) {
hidden = rb_find_bss(rdev, tmp, BSS_CMP_HIDE_ZLEN);
@@ -1983,10 +1979,15 @@ cfg80211_inform_single_bss_data(struct w
spin_lock_bh(&rdev->bss_lock);
if (cfg80211_add_nontrans_list(non_tx_data->tx_bss,
&res->pub)) {
- if (__cfg80211_unlink_bss(rdev, res))
+ if (__cfg80211_unlink_bss(rdev, res)) {
rdev->bss_generation++;
+ res = NULL;
+ }
}
spin_unlock_bh(&rdev->bss_lock);
+
+ if (!res)
+ return NULL;
}
trace_cfg80211_return_bss(&res->pub);

View File

@ -1,48 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Sat, 1 Oct 2022 00:01:44 +0200
Subject: [PATCH] wifi: cfg80211: avoid nontransmitted BSS list
corruption
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit bcca852027e5878aec911a347407ecc88d6fff7f upstream.
If a non-transmitted BSS shares enough information (both
SSID and BSSID!) with another non-transmitted BSS of a
different AP, then we can find and update it, and then
try to add it to the non-transmitted BSS list. We do a
search for it on the transmitted BSS, but if it's not
there (but belongs to another transmitted BSS), the list
gets corrupted.
Since this is an erroneous situation, simply fail the
list insertion in this case and free the non-transmitted
BSS.
This fixes CVE-2022-42721.
Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -425,6 +425,15 @@ cfg80211_add_nontrans_list(struct cfg802
rcu_read_unlock();
+ /*
+ * This is a bit weird - it's not on the list, but already on another
+ * one! The only way that could happen is if there's some BSSID/SSID
+ * shared by multiple APs in their multi-BSSID profiles, potentially
+ * with hidden SSID mixed in ... ignore it.
+ */
+ if (!list_empty(&nontrans_bss->nontrans_list))
+ return -EINVAL;
+
/* add to the list */
list_add_tail(&nontrans_bss->nontrans_list, &trans_bss->nontrans_list);
return 0;

View File

@ -1,31 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 5 Oct 2022 15:10:09 +0200
Subject: [PATCH] wifi: mac80211_hwsim: avoid mac80211 warning on bad
rate
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit 1833b6f46d7e2830251a063935ab464256defe22 upstream.
If the tool on the other side (e.g. wmediumd) gets confused
about the rate, we hit a warning in mac80211. Silence that
by effectively duplicating the check here and dropping the
frame silently (in mac80211 it's dropped with the warning).
Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -3760,6 +3760,8 @@ static int hwsim_cloned_frame_received_n
rx_status.band = channel->band;
rx_status.rate_idx = nla_get_u32(info->attrs[HWSIM_ATTR_RX_RATE]);
+ if (rx_status.rate_idx >= data2->hw->wiphy->bands[rx_status.band]->n_bitrates)
+ goto out;
rx_status.signal = nla_get_u32(info->attrs[HWSIM_ATTR_SIGNAL]);
hdr = (void *)skb->data;

View File

@ -1,52 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 5 Oct 2022 21:24:10 +0200
Subject: [PATCH] wifi: mac80211: fix crash in beacon protection for
P2P-device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit b2d03cabe2b2e150ff5a381731ea0355459be09f upstream.
If beacon protection is active but the beacon cannot be
decrypted or is otherwise malformed, we call the cfg80211
API to report this to userspace, but that uses a netdev
pointer, which isn't present for P2P-Device. Fix this to
call it only conditionally to ensure cfg80211 won't crash
in the case of P2P-Device.
This fixes CVE-2022-42722.
Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Fixes: 9eaf183af741 ("mac80211: Report beacon protection failures to user space")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1986,10 +1986,11 @@ ieee80211_rx_h_decrypt(struct ieee80211_
if (mmie_keyidx < NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS ||
mmie_keyidx >= NUM_DEFAULT_KEYS + NUM_DEFAULT_MGMT_KEYS +
- NUM_DEFAULT_BEACON_KEYS) {
- cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
- skb->data,
- skb->len);
+ NUM_DEFAULT_BEACON_KEYS) {
+ if (rx->sdata->dev)
+ cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
+ skb->data,
+ skb->len);
return RX_DROP_MONITOR; /* unexpected BIP keyidx */
}
@@ -2137,7 +2138,8 @@ ieee80211_rx_h_decrypt(struct ieee80211_
/* either the frame has been decrypted or will be dropped */
status->flag |= RX_FLAG_DECRYPTED;
- if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE))
+ if (unlikely(ieee80211_is_beacon(fc) && result == RX_DROP_UNUSABLE &&
+ rx->sdata->dev))
cfg80211_rx_unprot_mlme_mgmt(rx->sdata->dev,
skb->data, skb->len);

View File

@ -1,85 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 5 Oct 2022 23:11:43 +0200
Subject: [PATCH] wifi: cfg80211: update hidden BSSes to avoid WARN_ON
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
commit c90b93b5b782891ebfda49d4e5da36632fefd5d1 upstream.
When updating beacon elements in a non-transmitted BSS,
also update the hidden sub-entries to the same beacon
elements, so that a future update through other paths
won't trigger a WARN_ON().
The warning is triggered because the beacon elements in
the hidden BSSes that are children of the BSS should
always be the same as in the parent.
Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1609,6 +1609,23 @@ struct cfg80211_non_tx_bss {
u8 bssid_index;
};
+static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
+ const struct cfg80211_bss_ies *new_ies,
+ const struct cfg80211_bss_ies *old_ies)
+{
+ struct cfg80211_internal_bss *bss;
+
+ /* Assign beacon IEs to all sub entries */
+ list_for_each_entry(bss, &known->hidden_list, hidden_list) {
+ const struct cfg80211_bss_ies *ies;
+
+ ies = rcu_access_pointer(bss->pub.beacon_ies);
+ WARN_ON(ies != old_ies);
+
+ rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
+ }
+}
+
static bool
cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
struct cfg80211_internal_bss *known,
@@ -1632,7 +1649,6 @@ cfg80211_update_known_bss(struct cfg8021
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
} else if (rcu_access_pointer(new->pub.beacon_ies)) {
const struct cfg80211_bss_ies *old;
- struct cfg80211_internal_bss *bss;
if (known->pub.hidden_beacon_bss &&
!list_empty(&known->hidden_list)) {
@@ -1660,16 +1676,7 @@ cfg80211_update_known_bss(struct cfg8021
if (old == rcu_access_pointer(known->pub.ies))
rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
- /* Assign beacon IEs to all sub entries */
- list_for_each_entry(bss, &known->hidden_list, hidden_list) {
- const struct cfg80211_bss_ies *ies;
-
- ies = rcu_access_pointer(bss->pub.beacon_ies);
- WARN_ON(ies != old);
-
- rcu_assign_pointer(bss->pub.beacon_ies,
- new->pub.beacon_ies);
- }
+ cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
if (old)
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
@@ -2319,6 +2326,8 @@ cfg80211_update_notlisted_nontrans(struc
} else {
old = rcu_access_pointer(nontrans_bss->beacon_ies);
rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
+ cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
+ new_ies, old);
rcu_assign_pointer(nontrans_bss->ies, new_ies);
if (old)
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);

View File

@ -1,77 +0,0 @@
From 4db561ae4a90c2d0e15996634567559e292dc9e5 Mon Sep 17 00:00:00 2001
From: Ahmed Zaki <anzaki@gmail.com>
Date: Sat, 2 Oct 2021 08:53:29 -0600
Subject: [PATCH] mac80211: fix a memory leak where sta_info is not freed
commit 8f9dcc29566626f683843ccac6113a12208315ca upstream.
The following is from a system that went OOM due to a memory leak:
wlan0: Allocated STA 74:83:c2:64:0b:87
wlan0: Allocated STA 74:83:c2:64:0b:87
wlan0: IBSS finish 74:83:c2:64:0b:87 (---from ieee80211_ibss_add_sta)
wlan0: Adding new IBSS station 74:83:c2:64:0b:87
wlan0: moving STA 74:83:c2:64:0b:87 to state 2
wlan0: moving STA 74:83:c2:64:0b:87 to state 3
wlan0: Inserted STA 74:83:c2:64:0b:87
wlan0: IBSS finish 74:83:c2:64:0b:87 (---from ieee80211_ibss_work)
wlan0: Adding new IBSS station 74:83:c2:64:0b:87
wlan0: moving STA 74:83:c2:64:0b:87 to state 2
wlan0: moving STA 74:83:c2:64:0b:87 to state 3
.
.
wlan0: expiring inactive not authorized STA 74:83:c2:64:0b:87
wlan0: moving STA 74:83:c2:64:0b:87 to state 2
wlan0: moving STA 74:83:c2:64:0b:87 to state 1
wlan0: Removed STA 74:83:c2:64:0b:87
wlan0: Destroyed STA 74:83:c2:64:0b:87
The ieee80211_ibss_finish_sta() is called twice on the same STA from 2
different locations. On the second attempt, the allocated STA is not
destroyed creating a kernel memory leak.
This is happening because sta_info_insert_finish() does not call
sta_info_free() the second time when the STA already exists (returns
-EEXIST). Note that the caller sta_info_insert_rcu() assumes STA is
destroyed upon errors.
Same fix is applied to -ENOMEM.
Signed-off-by: Ahmed Zaki <anzaki@gmail.com>
Link: https://lore.kernel.org/r/20211002145329.3125293-1-anzaki@gmail.com
[change the error path label to use the existing code]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Viacheslav Sablin <sablin@ispras.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/sta_info.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -646,13 +646,13 @@ static int sta_info_insert_finish(struct
/* check if STA exists already */
if (sta_info_get_bss(sdata, sta->sta.addr)) {
err = -EEXIST;
- goto out_err;
+ goto out_cleanup;
}
sinfo = kzalloc(sizeof(struct station_info), GFP_KERNEL);
if (!sinfo) {
err = -ENOMEM;
- goto out_err;
+ goto out_cleanup;
}
local->num_sta++;
@@ -708,8 +708,8 @@ static int sta_info_insert_finish(struct
out_drop_sta:
local->num_sta--;
synchronize_net();
+ out_cleanup:
cleanup_single_sta(sta);
- out_err:
mutex_unlock(&local->sta_mtx);
kfree(sinfo);
rcu_read_lock();

View File

@ -1,47 +0,0 @@
From 552ba102a6898630a7d16887f29e606d6fabe508 Mon Sep 17 00:00:00 2001
From: Siddh Raman Pant <code@siddh.me>
Date: Sun, 14 Aug 2022 20:45:12 +0530
Subject: [PATCH] wifi: mac80211: Don't finalize CSA in IBSS mode if state is
disconnected
commit 15bc8966b6d3a5b9bfe4c9facfa02f2b69b1e5f0 upstream.
When we are not connected to a channel, sending channel "switch"
announcement doesn't make any sense.
The BSS list is empty in that case. This causes the for loop in
cfg80211_get_bss() to be bypassed, so the function returns NULL
(check line 1424 of net/wireless/scan.c), causing the WARN_ON()
in ieee80211_ibss_csa_beacon() to get triggered (check line 500
of net/mac80211/ibss.c), which was consequently reported on the
syzkaller dashboard.
Thus, check if we have an existing connection before generating
the CSA beacon in ieee80211_ibss_finish_csa().
Cc: stable@vger.kernel.org
Fixes: cd7760e62c2a ("mac80211: add support for CSA in IBSS mode")
Link: https://syzkaller.appspot.com/bug?id=05603ef4ae8926761b678d2939a3b2ad28ab9ca6
Reported-by: syzbot+b6c9fe29aefe68e4ad34@syzkaller.appspotmail.com
Signed-off-by: Siddh Raman Pant <code@siddh.me>
Tested-by: syzbot+b6c9fe29aefe68e4ad34@syzkaller.appspotmail.com
Link: https://lore.kernel.org/r/20220814151512.9985-1-code@siddh.me
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/ibss.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -534,6 +534,10 @@ int ieee80211_ibss_finish_csa(struct iee
sdata_assert_lock(sdata);
+ /* When not connected/joined, sending CSA doesn't make sense. */
+ if (ifibss->state != IEEE80211_IBSS_MLME_JOINED)
+ return -ENOLINK;
+
/* update cfg80211 bss information with the new channel */
if (!is_zero_ether_addr(ifibss->bssid)) {
cbss = cfg80211_get_bss(sdata->local->hw.wiphy,

View File

@ -1,55 +0,0 @@
From 5d20c6f932f2758078d0454729129c894fe353e7 Mon Sep 17 00:00:00 2001
From: Siddh Raman Pant <code@siddh.me>
Date: Sat, 20 Aug 2022 01:33:40 +0530
Subject: [PATCH] wifi: mac80211: Fix UAF in ieee80211_scan_rx()
commit 60deb9f10eec5c6a20252ed36238b55d8b614a2c upstream.
ieee80211_scan_rx() tries to access scan_req->flags after a
null check, but a UAF is observed when the scan is completed
and __ieee80211_scan_completed() executes, which then calls
cfg80211_scan_done() leading to the freeing of scan_req.
Since scan_req is rcu_dereference()'d, prevent the racing in
__ieee80211_scan_completed() by ensuring that from mac80211's
POV it is no longer accessed from an RCU read critical section
before we call cfg80211_scan_done().
Cc: stable@vger.kernel.org
Link: https://syzkaller.appspot.com/bug?extid=f9acff9bf08a845f225d
Reported-by: syzbot+f9acff9bf08a845f225d@syzkaller.appspotmail.com
Suggested-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: Siddh Raman Pant <code@siddh.me>
Link: https://lore.kernel.org/r/20220819200340.34826-1-code@siddh.me
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mac80211/scan.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -465,16 +465,19 @@ static void __ieee80211_scan_completed(s
scan_req = rcu_dereference_protected(local->scan_req,
lockdep_is_held(&local->mtx));
- if (scan_req != local->int_scan_req) {
- local->scan_info.aborted = aborted;
- cfg80211_scan_done(scan_req, &local->scan_info);
- }
RCU_INIT_POINTER(local->scan_req, NULL);
RCU_INIT_POINTER(local->scan_sdata, NULL);
local->scanning = 0;
local->scan_chandef.chan = NULL;
+ synchronize_rcu();
+
+ if (scan_req != local->int_scan_req) {
+ local->scan_info.aborted = aborted;
+ cfg80211_scan_done(scan_req, &local->scan_info);
+ }
+
/* Set power back to normal operating levels. */
ieee80211_hw_config(local, 0);

View File

@ -87,7 +87,7 @@
CFG80211_TESTMODE_DUMP(ieee80211_testmode_dump)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1448,6 +1448,7 @@ struct ieee80211_local {
@@ -1447,6 +1447,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */

View File

@ -0,0 +1,13 @@
--- a/mt7915/init.c
+++ b/mt7915/init.c
@@ -327,8 +327,8 @@ mt7915_init_wiphy(struct ieee80211_hw *h
struct mt7915_dev *dev = phy->dev;
hw->queues = 4;
- hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
- hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
+ hw->max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
+ hw->max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF_HE;
hw->netdev_features = NETIF_F_RXCSUM;
hw->radiotap_timestamp.units_pos =