FAILED: patch "[PATCH] wifi: mac80211: refuse to make a monitor active when it has" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.6.y
git checkout FETCH_HEAD
git cherry-pick -x 2b04d6556964ae9f89819b86a0a7801e39c3aae5
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092222-setback-rupture-f2fe@gregkh' --subject-prefix 'PATCH 6.6.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 2b04d6556964ae9f89819b86a0a7801e39c3aae5 Mon Sep 17 00:00:00 2001
From: Devin Wittmayer <[email protected]>
Date: Fri, 4 Sep 2026 13:03:38 -0700
Subject: [PATCH] wifi: mac80211: refuse to make a monitor active when it has
no queue
A monitor interface only gets a TXQ if it's created active, and one can't be added later. Setting the flag on a down interface is still allowed, so the driver is handed a monitor with no queue. ath9k dereferences it:
BUG: kernel NULL pointer dereference, address: 0000000000000066 RIP: 0010:ath_tx_node_init+0x49/0x170 [ath9k] ath9k_add_interface+0x10c/0x140 [ath9k] drv_add_interface+0x54/0x250 [mac80211] ieee80211_do_open+0x32f/0x800 [mac80211]
Reached with CAP_NET_ADMIN by "iw dev X set monitor active" followed by "ip link set X up". RTNL is held, so netlink operations block behind it.
Refuse the flag when there is no queue to give.
net/mac80211/cfg.c +4 -0
@@ -115,6 +115,10 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,return -EBUSY ; } +/* TXQs are reserved in ieee80211_if_add() and cannot be added later */ +if ((params->flags &MONITOR_FLAG_ACTIVE ) && !sdata->vif.txq) +return -EOPNOTSUPP ; +/* validate whether MU-MIMO can be configured */ if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) && !ieee80211_hw_check(&local->hw, NO_VIRTUAL_MONITOR) &&
Sasha Levin
maintainerPATCH 1/3 wifi: cfg80211: pass net_device to .set_monitor_channel
From: Felix Fietkau <[email protected]>
[ Upstream commit 9c4f830927750a2bf9fd9426a5257f0fdce3b662 ]
Preparation for allowing multiple monitor interfaces with different channels on a multi-radio wiphy.
Stable-dep-of: 2b04d6556964 ("wifi: mac80211: refuse to make a monitor active when it has no queue")
--- drivers/net/wireless/ath/wil6210/cfg80211.c | 1 + drivers/net/wireless/marvell/libertas/cfg.c | 1 + drivers/net/wireless/microchip/wilc1000/cfg80211.c | 3 ++- include/net/cfg80211.h | 1 + net/mac80211/cfg.c | 1 + net/wireless/chan.c | 3 ++- net/wireless/core.h | 1 + net/wireless/nl80211.c | 2 +- net/wireless/rdev-ops.h | 5 +++-- net/wireless/trace.h | 10 ++++++---- net/wireless/wext-compat.c | 2 +- 11 files changed, 20 insertions(+), 10 deletions(-)
drivers/net/wireless/ath/wil6210/cfg80211.c +1 -0
@@ -1496,6 +1496,7 @@ int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, }static int wil_cfg80211_set_channel (struct wiphy *wiphy, +struct net_device *dev,struct cfg80211_chan_def *chandef) {struct wil6210_priv *wil =wiphy_to_wil (wiphy);
drivers/net/wireless/marvell/libertas/cfg.c +1 -0
@@ -486,6 +486,7 @@ static int lbs_add_wps_enrollee_tlv(u8 *tlv, const u8 *ie, size_t ie_len)*/ static int lbs_cfg_set_monitor_channel (struct wiphy *wiphy, +struct net_device *dev,struct cfg80211_chan_def *chandef) {struct lbs_private *priv =wiphy_priv (wiphy);
drivers/net/wireless/microchip/wilc1000/cfg80211.c +2 -1
@@ -233,6 +233,7 @@ struct wilc_vif *wilc_get_wl_to_vif(struct wilc *wl) }static int set_channel (struct wiphy *wiphy, +struct net_device *dev,struct cfg80211_chan_def *chandef) {struct wilc *wl =wiphy_priv (wiphy);
@@ -1430,7 +1431,7 @@ static int start_ap(struct wiphy *wiphy, struct net_device *dev,struct wilc_vif *vif =netdev_priv (dev);int ret; - ret =set_channel (wiphy, &settings->chandef); + ret =set_channel (wiphy, dev, &settings->chandef);if (ret !=0 )netdev_err (dev,"Error in setting channel\n" );
include/net/cfg80211.h +1 -0
@@ -4513,6 +4513,7 @@ struct cfg80211_ops { struct ieee80211_channel *chan);int (*set_monitor_channel)(struct wiphy *wiphy, +struct net_device *dev,struct cfg80211_chan_def *chandef); int (*scan)(struct wiphy *wiphy,
net/mac80211/cfg.c +1 -0
@@ -907,6 +907,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, }static int ieee80211_set_monitor_channel (struct wiphy *wiphy, +struct net_device *dev,struct cfg80211_chan_def *chandef) {struct ieee80211_local *local =wiphy_priv (wiphy);
net/wireless/chan.c +2 -1
@@ -1389,6 +1389,7 @@ bool cfg80211_reg_can_beacon_relax(struct wiphy *wiphy,EXPORT_SYMBOL (cfg80211_reg_can_beacon_relax);int cfg80211_set_monitor_channel (struct cfg80211_registered_device *rdev, +struct net_device *dev,struct cfg80211_chan_def *chandef) {if (!rdev->ops->set_monitor_channel)
@@ -1396,7 +1397,7 @@ int cfg80211_set_monitor_channel(struct cfg80211_registered_device *rdev,if (!cfg80211_has_monitors_only (rdev))return -EBUSY ; -return rdev_set_monitor_channel (rdev, chandef); +return rdev_set_monitor_channel (rdev, dev, chandef); } bool cfg80211_any_usable_channels(struct wiphy *wiphy,
net/wireless/core.h +1 -0
@@ -535,6 +535,7 @@ static inline unsigned int elapsed_jiffies_msecs(unsigned long start) }int cfg80211_set_monitor_channel (struct cfg80211_registered_device *rdev, +struct net_device *dev,struct cfg80211_chan_def *chandef); int ieee80211_get_ratemask(struct ieee80211_supported_band *sband,
net/wireless/nl80211.c +1 -1
@@ -3443,7 +3443,7 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,case NL80211_IFTYPE_MESH_POINT :return cfg80211_set_mesh_channel (rdev, wdev, &chandef);case NL80211_IFTYPE_MONITOR : -return cfg80211_set_monitor_channel (rdev, &chandef); +return cfg80211_set_monitor_channel (rdev, dev, &chandef);default :break ; }
net/wireless/rdev-ops.h +3 -2
@@ -445,11 +445,12 @@ rdev_libertas_set_mesh_channel(struct cfg80211_registered_device *rdev,static inline int rdev_set_monitor_channel (struct cfg80211_registered_device *rdev, +struct net_device *dev,struct cfg80211_chan_def *chandef) {int ret; -trace_rdev_set_monitor_channel (&rdev->wiphy, chandef); - ret = rdev->ops->set_monitor_channel (&rdev->wiphy, chandef); +trace_rdev_set_monitor_channel (&rdev->wiphy, dev, chandef); + ret = rdev->ops->set_monitor_channel (&rdev->wiphy, dev, chandef);trace_rdev_return_int (&rdev->wiphy, ret);return ret; }
net/wireless/trace.h +6 -4
@@ -1222,19 +1222,21 @@ TRACE_EVENT(rdev_libertas_set_mesh_channel, );TRACE_EVENT (rdev_set_monitor_channel, - TP_PROTO(struct wiphy *wiphy, + TP_PROTO(struct wiphy *wiphy, struct net_device *netdev, struct cfg80211_chan_def *chandef), -TP_ARGS (wiphy, chandef), +TP_ARGS (wiphy, netdev, chandef),TP_STRUCT__entry ( WIPHY_ENTRY + NETDEV_ENTRYCHAN_DEF_ENTRY ),TP_fast_assign ( WIPHY_ASSIGN; + NETDEV_ASSIGN; CHAN_DEF_ASSIGN(chandef); ), -TP_printk (WIPHY_PR_FMT ", " CHAN_DEF_PR_FMT , -WIPHY_PR_ARG ,CHAN_DEF_PR_ARG ) +TP_printk (WIPHY_PR_FMT ", " NETDEV_PR_FMT ", " CHAN_DEF_PR_FMT , +WIPHY_PR_ARG ,NETDEV_PR_ARG ,CHAN_DEF_PR_ARG ) ); TRACE_EVENT(rdev_auth,
net/wireless/wext-compat.c +1 -1
@@ -851,7 +851,7 @@ static int cfg80211_wext_siwfreq(struct net_device *dev, ret = -EINVAL ;break ; } - ret =cfg80211_set_monitor_channel (rdev, &chandef); + ret =cfg80211_set_monitor_channel (rdev, dev, &chandef);break ;case NL80211_IFTYPE_MESH_POINT : freq =cfg80211_wext_freq (wextfreq);
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/3 wifi: mac80211: track MU-MIMO configuration on disabled interfaces
From: Benjamin Berg <[email protected]>
[ Upstream commit a5aa46f1ac4f53e03b9b75cbf55634131f2f8cac ]
For monitoring, userspace will try to configure the VIF sdata, while the driver may see the monitor_sdata that is created when only monitor interfaces are up. This causes the odd situation that it may not be possible to store the MU-MIMO configuration on monitor_sdata.
Fix this by storing that information on the VIF sdata and updating the monitor_sdata when available and the interface is up. Also, adjust the code that adds monitor_sdata so that it will configure MU-MIMO based on the newly added interface or one of the existing ones.
This should give a mostly consistent behaviour when configuring MU-MIMO on sniffer interfaces. Should the user configure MU-MIMO on multiple sniffer interfaces, then mac80211 will simply select one of the configurations. This behaviour should be good enough and avoids breaking user expectations in the common scenarios.
Backport notes for 6.6:
Keep the MU-MIMO configuration on the userspace VIF while it is down and copy it to the virtual monitor when it is created or reconfigured. Drop NO_VIRTUAL_MONITOR branches because this tree only has WANT_MONITOR_VIF. Keep the existing monitor counter and virtual-monitor creation conditions; opening another passive monitor also updates an existing virtual monitor. Use u.mntr.list when walking mon_list, matching this tree's list linkage. Update the existing wake_up call in ieee80211_reconfig() instead of adding a second call at the newer upstream location. No functions are added.
Also complete the preceding .set_monitor_channel API conversion for the orinoco driver, which exists in 6.6 but was already removed upstream. Its existing callback needs the new net_device argument to match cfg80211_ops and build with incompatible-pointer-type errors enabled.
This retains the validation block needed for target 2b04d6556964 ("wifi: mac80211: refuse to make a monitor active when it has no queue") to cherry-pick cleanly, without importing newer monitor infrastructure.
Stable-dep-of: 2b04d6556964 ("wifi: mac80211: refuse to make a monitor active when it has no queue")
--- drivers/net/wireless/intersil/orinoco/cfg.c | 1 + net/mac80211/cfg.c | 39 +++++++++++++----- net/mac80211/ieee80211_i.h | 3 +- net/mac80211/iface.c | 44 ++++++++++++++++++--- net/mac80211/util.c | 3 +- 5 files changed, 72 insertions(+), 18 deletions(-)
drivers/net/wireless/intersil/orinoco/cfg.c +1 -0
@@ -162,6 +162,7 @@ static int orinoco_scan(struct wiphy *wiphy, }static int orinoco_set_monitor_channel (struct wiphy *wiphy, +struct net_device *dev,struct cfg80211_chan_def *chandef) {struct orinoco_private *priv =wiphy_priv (wiphy);
net/mac80211/cfg.c +29 -10
@@ -63,12 +63,14 @@ static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata,memcpy (sdata->vif.bss_conf.mu_group.position, params->vht_mumimo_groups +WLAN_MEMBERSHIP_LEN ,WLAN_USER_POSITION_LEN ); -ieee80211_link_info_change_notify (sdata, &sdata->deflink, -BSS_CHANGED_MU_GROUPS ); +/* don't care about endianness - just check for 0 */ memcpy (&membership, params->vht_mumimo_groups,WLAN_MEMBERSHIP_LEN ); mu_mimo_groups = membership !=0 ; + +/* Unset following if configured explicitly */ +eth_broadcast_addr (sdata->u.mntr.mu_follow_addr); }if (params->vht_mumimo_follow_addr) {
@@ -76,16 +78,26 @@ static void ieee80211_set_mu_mimo_follow(struct ieee80211_sub_if_data *sdata,is_valid_ether_addr (params->vht_mumimo_follow_addr);ether_addr_copy (sdata->u.mntr.mu_follow_addr, params->vht_mumimo_follow_addr); + +/* Unset current membership until a management frame is RXed */ +memset (sdata->vif.bss_conf.mu_group.membership,0 , +WLAN_MEMBERSHIP_LEN ); } sdata->vif.bss_conf.mu_mimo_owner = mu_mimo_groups || mu_mimo_follow; + +/* Notify only after setting mu_mimo_owner */ +if (sdata->vif.bss_conf.mu_mimo_owner && + sdata->flags &IEEE80211_SDATA_IN_DRIVER ) +ieee80211_link_info_change_notify (sdata, &sdata->deflink, +BSS_CHANGED_MU_GROUPS ); }static int ieee80211_set_mon_options (struct ieee80211_sub_if_data *sdata,struct vif_params *params) {struct ieee80211_local *local = sdata->local; -struct ieee80211_sub_if_data *monitor_sdata; +struct ieee80211_sub_if_data *monitor_sdata =NULL ;/* check flags first */ if (params->flags &&ieee80211_sdata_running (sdata)) {
@@ -104,18 +116,25 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,return -EBUSY ; } -/* also validate MU-MIMO change */ - monitor_sdata =wiphy_dereference (local->hw.wiphy, - local->monitor_sdata); - -if (!monitor_sdata && +/* validate whether MU-MIMO can be configured */ +if (!ieee80211_hw_check (&local->hw,WANT_MONITOR_VIF ) && (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))return -EOPNOTSUPP ; +/* Also update dependent monitor_sdata if required */ +if (test_bit (SDATA_STATE_RUNNING , &sdata->state)) + monitor_sdata =wiphy_dereference (local->hw.wiphy, + local->monitor_sdata); +/* apply all changes now - no failures allowed */ -if (monitor_sdata) -ieee80211_set_mu_mimo_follow (monitor_sdata, params); +if (ieee80211_hw_check (&local->hw,WANT_MONITOR_VIF )) { +/* This is copied in when the VIF is activated */ +ieee80211_set_mu_mimo_follow (sdata, params); + +if (monitor_sdata) +ieee80211_set_mu_mimo_follow (monitor_sdata, params); + }if (params->flags) {if (ieee80211_sdata_running (sdata)) {
net/mac80211/ieee80211_i.h +2 -1
@@ -2027,7 +2027,8 @@ void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata, const int offset);int ieee80211_do_open (struct wireless_dev *wdev,bool coming_up);void ieee80211_sdata_stop (struct ieee80211_sub_if_data *sdata); -int ieee80211_add_virtual_monitor (struct ieee80211_local *local); +int ieee80211_add_virtual_monitor (struct ieee80211_local *local, +struct ieee80211_sub_if_data *creator_sdata);void ieee80211_del_virtual_monitor (struct ieee80211_local *local);bool __ieee80211_recalc_txpower (struct ieee80211_sub_if_data *sdata);
net/mac80211/iface.c +38 -6
75 lines not on this page · raw message
net/mac80211/util.c +2 -1
@@ -2908,8 +2908,9 @@ int ieee80211_reconfig(struct ieee80211_local *local) wake_up: +/* Passing NULL means an interface is picked for configuration */ if (local->monitors == local->open_count && local->monitors >0 ) -ieee80211_add_virtual_monitor (local); +ieee80211_add_virtual_monitor (local,NULL );/* * Clear the WLAN_STA_BLOCK_BA flag so new aggregation
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/3 wifi: mac80211: refuse to make a monitor active when it has no queue
In reply to Sasha LevinFrom: Devin Wittmayer <[email protected]>
[ Upstream commit 2b04d6556964ae9f89819b86a0a7801e39c3aae5 ]
A monitor interface only gets a TXQ if it's created active, and one can't be added later. Setting the flag on a down interface is still allowed, so the driver is handed a monitor with no queue. ath9k dereferences it:
BUG: kernel NULL pointer dereference, address: 0000000000000066 RIP: 0010:ath_tx_node_init+0x49/0x170 [ath9k] ath9k_add_interface+0x10c/0x140 [ath9k] drv_add_interface+0x54/0x250 [mac80211] ieee80211_do_open+0x32f/0x800 [mac80211]
Reached with CAP_NET_ADMIN by "iw dev X set monitor active" followed by "ip link set X up". RTNL is held, so netlink operations block behind it.
Refuse the flag when there is no queue to give.
--- net/mac80211/cfg.c | 4 ++++ 1 file changed, 4 insertions(+)
net/mac80211/cfg.c +4 -0
@@ -116,6 +116,10 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,return -EBUSY ; } +/* TXQs are reserved in ieee80211_if_add() and cannot be added later */ +if ((params->flags &MONITOR_FLAG_ACTIVE ) && !sdata->vif.txq) +return -EOPNOTSUPP ; +/* validate whether MU-MIMO can be configured */ if (!ieee80211_hw_check (&local->hw,WANT_MONITOR_VIF ) && (params->vht_mumimo_groups || params->vht_mumimo_follow_addr))
Signature · 1 line
2.53.0