]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
wifi: mac80211: use monitor sdata with driver only if desired
authorJohannes Berg <johannes.berg@intel.com>
Thu, 25 Jul 2024 16:48:36 +0000 (18:48 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 11 Aug 2024 10:58:01 +0000 (12:58 +0200)
commit 8f4fa0876231c426f880a2bff25ac49fac67d805 upstream.

In commit 0d9c2beed116 ("wifi: mac80211: fix monitor channel
with chanctx emulation") I changed mac80211 to always have an
internal monitor_sdata to have something to have the chanctx
bound to.

However, if the driver didn't also have the WANT_MONITOR flag
this would cause mac80211 to allocate it without telling the
driver (which was intentional) but also use it for later APIs
to the driver without it ever having known about it which was
_not_ intentional.

Check through the code and only use the monitor_sdata in the
relevant places (TX, MU-MIMO follow settings, TX power, and
interface iteration) when the WANT_MONITOR flag is set.

Cc: stable@vger.kernel.org
Fixes: 0d9c2beed116 ("wifi: mac80211: fix monitor channel with chanctx emulation")
Reported-by: ZeroBeat <ZeroBeat@gmx.de>
Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219086
Tested-by: Lorenzo Bianconi <lorenzo@kernel.org>
Link: https://patch.msgid.link/20240725184836.25d334157a8e.I02574086da2c5cf0e18264ce5807db6f14ffd9c0@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/mac80211/cfg.c
net/mac80211/tx.c
net/mac80211/util.c

index 83ad6c9709fe609414dc2a9a3519fc943293a2c5..87a7b569cc77484f6f2f8b9c33e2b1c4e29016fa 100644 (file)
@@ -114,7 +114,7 @@ static int ieee80211_set_mon_options(struct ieee80211_sub_if_data *sdata,
 
        /* apply all changes now - no failures allowed */
 
-       if (monitor_sdata)
+       if (monitor_sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
                ieee80211_set_mu_mimo_follow(monitor_sdata, params);
 
        if (params->flags) {
@@ -3038,6 +3038,9 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
                sdata = IEEE80211_WDEV_TO_SUB_IF(wdev);
 
                if (sdata->vif.type == NL80211_IFTYPE_MONITOR) {
+                       if (!ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF))
+                               return -EOPNOTSUPP;
+
                        sdata = wiphy_dereference(local->hw.wiphy,
                                                  local->monitor_sdata);
                        if (!sdata)
@@ -3100,7 +3103,7 @@ static int ieee80211_set_tx_power(struct wiphy *wiphy,
        if (has_monitor) {
                sdata = wiphy_dereference(local->hw.wiphy,
                                          local->monitor_sdata);
-               if (sdata) {
+               if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
                        sdata->deflink.user_power_level = local->user_power_level;
                        if (txp_type != sdata->vif.bss_conf.txpower_type)
                                update_txp_type = true;
index 72a9ba8bc5fd9764068e00d42755f3ba922418de..edba4a31844fb6251f35e249ea59ea74e951de2f 100644 (file)
@@ -1768,7 +1768,7 @@ static bool __ieee80211_tx(struct ieee80211_local *local,
                        break;
                }
                sdata = rcu_dereference(local->monitor_sdata);
-               if (sdata) {
+               if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
                        vif = &sdata->vif;
                        info->hw_queue =
                                vif->hw_queue[skb_get_queue_mapping(skb)];
@@ -3957,7 +3957,8 @@ begin:
                        break;
                }
                tx.sdata = rcu_dereference(local->monitor_sdata);
-               if (tx.sdata) {
+               if (tx.sdata &&
+                   ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF)) {
                        vif = &tx.sdata->vif;
                        info->hw_queue =
                                vif->hw_queue[skb_get_queue_mapping(skb)];
index 771c05640aa3a8c8db318903501977a6623a7a57..c11dbe82ae1b3001865c56bf792f4b1dafa485b6 100644 (file)
@@ -776,7 +776,7 @@ static void __iterate_interfaces(struct ieee80211_local *local,
        sdata = rcu_dereference_check(local->monitor_sdata,
                                      lockdep_is_held(&local->iflist_mtx) ||
                                      lockdep_is_held(&local->hw.wiphy->mtx));
-       if (sdata &&
+       if (sdata && ieee80211_hw_check(&local->hw, WANT_MONITOR_VIF) &&
            (iter_flags & IEEE80211_IFACE_ITER_RESUME_ALL || !active_only ||
             sdata->flags & IEEE80211_SDATA_IN_DRIVER))
                iterator(data, sdata->vif.addr, &sdata->vif);