mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-01 10:45:49 +00:00
wifi: mac80211: use monitor sdata with driver only if desired
In commit0d9c2beed1
("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:0d9c2beed1
("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>
This commit is contained in:
parent
1722389b0d
commit
8f4fa08762
@ -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) {
|
||||
@ -3053,6 +3053,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)
|
||||
@ -3115,7 +3118,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;
|
||||
|
@ -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 @@ struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
|
||||
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)];
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user