A few fixes to start with:

- wext: fix notifier netns interaction
  - rsi: avoid TID OOB access
  - mac80211: reload pointer, fix A-MPDU flags
  - brcmfmac: fix DMA regression
  - cfg80211: fix regdb validation
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEEpeA8sTs3M8SN2hR410qiO8sPaAAFAmroaaMACgkQ10qiO8sP
 aACgfg/8D6WdzZKyj+piglNv7ZfuNthkKTzQmEY85MD4e4JwZG6q0AMW9/diR+XT
 7E6dgXI0LWvMYbeHWBeF22Fkf1YKqtm+gNRzffkzRqRKMooSqNGeBNbbmiEhHe2A
 ti7I4CvkHCjAv8ko+wVm7YW/POtWFICAb0llOI6/vjaYRvUm0RiIHjGhAM4vZC9c
 NM0rDFZIWxamXf2QjUEDKTzsouo00UzxEDc6KCsJG252g7HksTnd0TFXKj2HpA8N
 SzK5g6seVLx8On4ybjhz+pBa814DKc8JYHMiGkuf9KjHVgKR+7x9fi+nynnsZOJ4
 LLZjkXMkZLaPiEq/TV9z8eAtZ4+jkC5z2N/hNbhrZf9T/qqOUv/uJ8blURqhywol
 ZRbXKZXtWjsn+OvpJhpZ0TjyQKHWSk+AaDWHjDs1kK07et4GQ0z67rEyYSNX42G8
 VgHVf8XYX4vaQQOg1+XMiEVxVb4k1UwF51dYhk/qIn9JS55FI3ObVdFVf3p++jKZ
 q6HDUmWuBIE0DyA0RGlSnkcxuzxUW+AJkD4dfZHWXYA+BgElx7Wq72KoFNDw/s6k
 xWXdbBsFOjMuaGP8e6SmKrQXAptQylZ5VEBDY4KSIxScH7UBtBUvY2TudiKIfNSm
 X/GYBvfhEpsX8fHXA41Nm++hap1oXZujsPR0dm2iCqTkfzYUWBM=
 =pZ1u
 -----END PGP SIGNATURE-----

Merge tag 'wireless-2026-11-02' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless

Johannes Berg says:

====================
A few fixes to start with:
 - wext: fix notifier netns interaction
 - rsi: avoid TID OOB access
 - mac80211: reload pointer, fix A-MPDU flags
 - brcmfmac: fix DMA regression
 - cfg80211: fix regdb validation

* tag 'wireless-2026-11-02' of https://git.kernel.org/pub/scm/linux/kernel/git/wireless/wireless:
  wifi: mac80211: reinstate IEEE80211_TX_CTL_AMPDU flag in ieee80211_tx_prep_agg()
  wifi: cfg80211: fix out-of-bounds read in valid_rule()
  wifi: rsi: Skip TX aggregation setup for non-QoS frames
  wifi: wext: Limit notifier event flushes to the device's netns
  wifi: brcmfmac: map msgbuf RX packet IDs bidirectional
  wifi: mac80211: reload TDLS header pointer after skb_linearize()
====================

Link: https://patch.msgid.link/20261102104649.727621-3-johannes@sipsolutions.net
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Paolo Abeni 2026-11-04 15:00:49 +01:00
commit c4328134f3
8 changed files with 32 additions and 23 deletions

View File

@ -1639,7 +1639,7 @@ int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
if (!msgbuf->tx_pktids)
goto fail;
msgbuf->rx_pktids = brcmf_msgbuf_init_pktids(NR_RX_PKTIDS,
DMA_FROM_DEVICE);
DMA_BIDIRECTIONAL);
if (!msgbuf->rx_pktids)
goto fail;

View File

@ -458,7 +458,7 @@ void rsi_core_xmit(struct rsi_common *common, struct sk_buff *skb)
tx_params->sta_id = 0;
}
if (rsta) {
if (rsta && tid < IEEE80211_NUM_TIDS) {
/* Start aggregation if not done for this tid */
if (!rsta->start_tx_aggr[tid]) {
rsta->start_tx_aggr[tid] = true;

View File

@ -201,6 +201,8 @@
#include <linux/wireless.h> /* IOCTL user space API */
#include <linux/if_ether.h>
struct net;
/***************************** VERSION *****************************/
/*
* This constant is used to know which version of the driver API is
@ -411,10 +413,10 @@ struct iw_spy_data {
void wireless_send_event(struct net_device *dev, unsigned int cmd,
union iwreq_data *wrqu, const char *extra);
#ifdef CONFIG_WEXT_CORE
/* flush all previous wext events - if work is done from netdev notifiers */
void wireless_nlevent_flush(void);
/* Flush previous wext events in this netns from netdev notifiers. */
void wireless_nlevent_flush(struct net *net);
#else
static inline void wireless_nlevent_flush(void) {}
static inline void wireless_nlevent_flush(struct net *net) {}
#endif
/* We may need a function to send a stream of events to user space.

View File

@ -2021,7 +2021,7 @@ void
ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
struct sk_buff *skb)
{
struct ieee80211_tdls_data *tf = (void *)skb->data;
struct ieee80211_tdls_data *tf;
struct wiphy *wiphy = sdata->local->hw.wiphy;
lockdep_assert_wiphy(wiphy);
@ -2037,6 +2037,7 @@ ieee80211_process_tdls_channel_switch(struct ieee80211_sub_if_data *sdata,
* The packet/size was already validated by mac80211 Rx path, only look
* at the action type.
*/
tf = (void *)skb->data;
switch (tf->action_code) {
case WLAN_TDLS_CHANNEL_SWITCH_REQUEST:
ieee80211_process_tdls_channel_switch_req(sdata, skb);

View File

@ -1164,6 +1164,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
struct sk_buff *purge_skb = NULL;
if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
info->flags |= IEEE80211_TX_CTL_AMPDU;
reset_agg_timer = true;
} else if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
/*
@ -1195,6 +1196,7 @@ static bool ieee80211_tx_prep_agg(struct ieee80211_tx_data *tx,
if (!tid_tx) {
/* do nothing, let packet pass through */
} else if (test_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state)) {
info->flags |= IEEE80211_TX_CTL_AMPDU;
reset_agg_timer = true;
} else {
queued = true;

View File

@ -1944,7 +1944,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb,
return NOTIFY_DONE;
}
wireless_nlevent_flush();
wireless_nlevent_flush(dev_net(dev));
return NOTIFY_OK;
}

View File

@ -680,6 +680,9 @@ static bool valid_rule(const u8 *data, unsigned int size, u16 rule_ptr)
/* mandatory fields */
if (rule->len < offsetofend(struct fwdb_rule, max_bw))
return false;
/* the rule must lie entirely within the database */
if ((u8 *)rule + rule->len > data + size)
return false;
if (rule->len >= offsetofend(struct fwdb_rule, wmm_ptr)) {
u32 wmm_ptr = be16_to_cpu(rule->wmm_ptr) << 2;
struct fwdb_wmm_rule *wmm;

View File

@ -342,32 +342,28 @@ static const int compat_event_type_size[] = {
/* IW event code */
void wireless_nlevent_flush(void)
void wireless_nlevent_flush(struct net *net)
{
struct sk_buff *skb;
struct net *net;
down_read(&net_rwsem);
for_each_net(net) {
while ((skb = skb_dequeue(&net->wext_nlevents)))
rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL,
GFP_KERNEL);
}
up_read(&net_rwsem);
while ((skb = skb_dequeue(&net->wext_nlevents)))
rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
}
EXPORT_SYMBOL_GPL(wireless_nlevent_flush);
static int wext_netdev_notifier_call(struct notifier_block *nb,
unsigned long state, void *ptr)
{
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
/*
* When a netdev changes state in any way, flush all pending messages
* to avoid them going out in a strange order, e.g. RTM_NEWLINK after
* RTM_DELLINK, or with IFF_UP after without IFF_UP during dev_close()
* or similar - all of which could otherwise happen due to delays from
* schedule_work().
* When a netdev changes state in any way, flush all pending messages in
* its network namespace to avoid them going out in a strange order,
* e.g. RTM_NEWLINK after RTM_DELLINK, or with IFF_UP after without
* IFF_UP during dev_close() or similar - all of which could otherwise
* happen due to delays from schedule_work().
*/
wireless_nlevent_flush();
wireless_nlevent_flush(dev_net(dev));
return NOTIFY_OK;
}
@ -410,7 +406,12 @@ subsys_initcall(wireless_nlevent_init);
/* Process events generated by the wireless layer or the driver. */
static void wireless_nlevent_process(struct work_struct *work)
{
wireless_nlevent_flush();
struct net *net;
down_read(&net_rwsem);
for_each_net(net)
wireless_nlevent_flush(net);
up_read(&net_rwsem);
}
static DECLARE_WORK(wireless_nlevent_work, wireless_nlevent_process);