[openwrt/openwrt] mac80211: backport some upstream fixes

LEDE Commits lede-commits at lists.infradead.org
Mon Nov 18 02:51:40 PST 2024


nbd pushed a commit to openwrt/openwrt.git, branch openwrt-24.10:
https://git.openwrt.org/585eb0d6c8bf5ec2016f245c6f5c5b60a14ec074

commit 585eb0d6c8bf5ec2016f245c6f5c5b60a14ec074
Author: Felix Fietkau <nbd at nbd.name>
AuthorDate: Mon Nov 18 11:21:02 2024 +0100

    mac80211: backport some upstream fixes
    
    Fix various issues, including potential crashes
    
    Signed-off-by: Felix Fietkau <nbd at nbd.name>
    (cherry picked from commit 53eab6198bf87d12055409bc4a38d58b68291b2f)
---
 ...11-fix-vif-addr-when-switching-from-monit.patch |  63 +++++++++
 ...11-fix-incorrect-timing-to-initialize-sta.patch |  32 +++++
 ...11-ieee80211_i-Fix-memory-corruption-bug-.patch |  53 ++++++++
 ...211-fix-user-power-when-emulating-chanctx.patch |  24 ++++
 ...i-cfg80211-Add-wiphy_delayed_work_pending.patch |  83 ++++++++++++
 ...11-Convert-color-collision-detection-to-w.patch | 148 +++++++++++++++++++++
 6 files changed, 403 insertions(+)

diff --git a/package/kernel/mac80211/patches/subsys/361-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch b/package/kernel/mac80211/patches/subsys/361-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch
new file mode 100644
index 0000000000..f4cfc95aa3
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/361-wifi-mac80211-fix-vif-addr-when-switching-from-monit.patch
@@ -0,0 +1,63 @@
+From: Felix Fietkau <nbd at nbd.name>
+Date: Fri, 15 Nov 2024 12:28:43 +0100
+Subject: [PATCH] wifi: mac80211: fix vif addr when switching from monitor
+ to station
+
+Since adding support for opting out of virtual monitor support, a zero vif
+addr was used to indicate passive vs active monitor to the driver.
+This would break the vif->addr when changing the netdev mac address before
+switching the interface from monitor to sta mode.
+Fix the regression by adding a separate flag to indicate whether vif->addr
+is valid.
+
+Reported-by: syzbot+9ea265d998de25ac6a46 at syzkaller.appspotmail.com
+Fixes: 9d40f7e32774 ("wifi: mac80211: add flag to opt out of virtual monitor support")
+Signed-off-by: Felix Fietkau <nbd at nbd.name>
+---
+
+--- a/include/net/mac80211.h
++++ b/include/net/mac80211.h
+@@ -1972,6 +1972,8 @@ enum ieee80211_neg_ttlm_res {
+  * @neg_ttlm: negotiated TID to link mapping info.
+  *	see &struct ieee80211_neg_ttlm.
+  * @addr: address of this interface
++ * @addr_valid: indicates if the address is actively used. Set to false for
++ *	passive monitor interfaces, true in all other cases.
+  * @p2p: indicates whether this AP or STA interface is a p2p
+  *	interface, i.e. a GO or p2p-sta respectively
+  * @netdev_features: tx netdev features supported by the hardware for this
+@@ -2011,6 +2013,7 @@ struct ieee80211_vif {
+ 	u16 valid_links, active_links, dormant_links, suspended_links;
+ 	struct ieee80211_neg_ttlm neg_ttlm;
+ 	u8 addr[ETH_ALEN] __aligned(2);
++	bool addr_valid;
+ 	bool p2p;
+ 
+ 	u8 cab_queue;
+--- a/net/mac80211/iface.c
++++ b/net/mac80211/iface.c
+@@ -279,13 +279,8 @@ static int _ieee80211_change_mac(struct
+ 	ret = eth_mac_addr(sdata->dev, sa);
+ 
+ 	if (ret == 0) {
+-		if (check_dup) {
+-			memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
+-			ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
+-		} else {
+-			memset(sdata->vif.addr, 0, ETH_ALEN);
+-			memset(sdata->vif.bss_conf.addr, 0, ETH_ALEN);
+-		}
++		memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
++		ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
+ 	}
+ 
+ 	/* Regardless of eth_mac_addr() return we still want to add the
+@@ -1324,6 +1319,8 @@ int ieee80211_do_open(struct wireless_de
+ 		}
+ 	}
+ 
++	sdata->vif.addr_valid = sdata->vif.type != NL80211_IFTYPE_MONITOR ||
++				(sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE);
+ 	switch (sdata->vif.type) {
+ 	case NL80211_IFTYPE_AP_VLAN:
+ 		/* no need to tell driver, but set carrier and chanctx */
diff --git a/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-fix-incorrect-timing-to-initialize-sta.patch b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-fix-incorrect-timing-to-initialize-sta.patch
new file mode 100644
index 0000000000..94e51afd85
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/362-wifi-mac80211-fix-incorrect-timing-to-initialize-sta.patch
@@ -0,0 +1,32 @@
+From: Benjamin Lin <benjamin-jw.lin at mediatek.com>
+Date: Mon, 18 Nov 2024 16:07:22 +0800
+Subject: [PATCH] wifi: mac80211: fix incorrect timing to initialize
+ station NSS capability
+
+Station's spatial streaming capability should be initialized before
+handling VHT OMN, because the handling requires the capability information.
+
+Fixes: a8bca3e9371d ("wifi: mac80211: track capability/opmode NSS separately")
+Signed-off-by: Benjamin Lin <benjamin-jw.lin at mediatek.com>
+---
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -1914,6 +1914,8 @@ static int sta_link_apply_parameters(str
+ 						    params->eht_capa_len,
+ 						    link_sta);
+ 
++	ieee80211_sta_init_nss(link_sta);
++
+ 	if (params->opmode_notif_used) {
+ 		/* returned value is only needed for rc update, but the
+ 		 * rc isn't initialized here yet, so ignore it
+@@ -1923,8 +1925,6 @@ static int sta_link_apply_parameters(str
+ 					      sband->band);
+ 	}
+ 
+-	ieee80211_sta_init_nss(link_sta);
+-
+ 	return 0;
+ }
+ 
diff --git a/package/kernel/mac80211/patches/subsys/363-wifi-mac80211-ieee80211_i-Fix-memory-corruption-bug-.patch b/package/kernel/mac80211/patches/subsys/363-wifi-mac80211-ieee80211_i-Fix-memory-corruption-bug-.patch
new file mode 100644
index 0000000000..dcdb89cd4a
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/363-wifi-mac80211-ieee80211_i-Fix-memory-corruption-bug-.patch
@@ -0,0 +1,53 @@
+From: "Gustavo A. R. Silva" <gustavoars at kernel.org>
+Date: Fri, 25 Oct 2024 16:05:50 -0600
+Subject: [PATCH] wifi: mac80211: ieee80211_i: Fix memory corruption bug in
+ struct ieee80211_chanctx
+
+Move the `struct ieee80211_chanctx_conf conf` to the end of
+`struct ieee80211_chanctx` and fix a memory corruption bug
+triggered e.g. in `hwsim_set_chanctx_magic()`: `radar_detected`
+is being overwritten when `cp->magic = HWSIM_CHANCTX_MAGIC;`
+See the function call sequence below:
+
+drv_add_chanctx(... struct ieee80211_chanctx *ctx) ->
+    local->ops->add_chanctx(&local->hw, &ctx->conf) ->
+	mac80211_hwsim_add_chanctx(... struct ieee80211_chanctx_conf *ctx) ->
+	    hwsim_set_chanctx_magic(ctx)
+
+This also happens in a number of other drivers.
+
+Also, add a code comment to try to prevent people from introducing
+new members after `struct ieee80211_chanctx_conf conf`. Notice that
+`struct ieee80211_chanctx_conf` is a flexible structure --a structure
+that contains a flexible-array member, so it should always be at
+the end of any other containing structures.
+
+This change also fixes 50 of the following warnings:
+
+net/mac80211/ieee80211_i.h:895:39: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end]
+
+-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
+getting ready to enable it, globally.
+
+Fixes: bca8bc0399ac ("wifi: mac80211: handle ieee80211_radar_detected() for MLO")
+Signed-off-by: Gustavo A. R. Silva <gustavoars at kernel.org>
+Link: https://patch.msgid.link/ZxwWPrncTeSi1UTq@kspp
+[also refer to other drivers in commit message]
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -894,9 +894,10 @@ struct ieee80211_chanctx {
+ 	/* temporary data for search algorithm etc. */
+ 	struct ieee80211_chan_req req;
+ 
+-	struct ieee80211_chanctx_conf conf;
+-
+ 	bool radar_detected;
++
++	/* MUST be last - ends in a flexible-array member. */
++	struct ieee80211_chanctx_conf conf;
+ };
+ 
+ struct mac80211_qos_map {
diff --git a/package/kernel/mac80211/patches/subsys/364-mac80211-fix-user-power-when-emulating-chanctx.patch b/package/kernel/mac80211/patches/subsys/364-mac80211-fix-user-power-when-emulating-chanctx.patch
new file mode 100644
index 0000000000..15db2c54e4
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/364-mac80211-fix-user-power-when-emulating-chanctx.patch
@@ -0,0 +1,24 @@
+From: Ben Greear <greearb at candelatech.com>
+Date: Thu, 10 Oct 2024 13:39:54 -0700
+Subject: [PATCH] mac80211: fix user-power when emulating chanctx
+
+ieee80211_calc_hw_conf_chan was ignoring the configured
+user_txpower.  If it is set, use it to potentially decrease
+txpower as requested.
+
+Signed-off-by: Ben Greear <greearb at candelatech.com>
+Link: https://patch.msgid.link/20241010203954.1219686-1-greearb@candelatech.com
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/main.c
++++ b/net/mac80211/main.c
+@@ -167,6 +167,8 @@ static u32 ieee80211_calc_hw_conf_chan(s
+ 	}
+ 
+ 	power = ieee80211_chandef_max_power(&chandef);
++	if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
++		power = min(local->user_power_level, power);
+ 
+ 	rcu_read_lock();
+ 	list_for_each_entry_rcu(sdata, &local->interfaces, list) {
diff --git a/package/kernel/mac80211/patches/subsys/365-wifi-cfg80211-Add-wiphy_delayed_work_pending.patch b/package/kernel/mac80211/patches/subsys/365-wifi-cfg80211-Add-wiphy_delayed_work_pending.patch
new file mode 100644
index 0000000000..981cc2433b
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/365-wifi-cfg80211-Add-wiphy_delayed_work_pending.patch
@@ -0,0 +1,83 @@
+From: Remi Pommarel <repk at triplefau.lt>
+Date: Tue, 24 Sep 2024 21:28:04 +0200
+Subject: [PATCH] wifi: cfg80211: Add wiphy_delayed_work_pending()
+
+Add wiphy_delayed_work_pending() to check if any delayed work timer is
+pending, that can be used to be sure that wiphy_delayed_work_queue()
+won't postpone an already pending delayed work.
+
+Signed-off-by: Remi Pommarel <repk at triplefau.lt>
+Link: https://patch.msgid.link/20240924192805.13859-2-repk@triplefau.lt
+[fix return value kernel-doc]
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/include/net/cfg80211.h
++++ b/include/net/cfg80211.h
+@@ -6141,6 +6141,50 @@ void wiphy_delayed_work_flush(struct wip
+ 			      struct wiphy_delayed_work *dwork);
+ 
+ /**
++ * wiphy_delayed_work_pending - Find out whether a wiphy delayable
++ * work item is currently pending.
++ *
++ * @wiphy: the wiphy, for debug purposes
++ * @dwork: the delayed work in question
++ *
++ * Return: true if timer is pending, false otherwise
++ *
++ * How wiphy_delayed_work_queue() works is by setting a timer which
++ * when it expires calls wiphy_work_queue() to queue the wiphy work.
++ * Because wiphy_delayed_work_queue() uses mod_timer(), if it is
++ * called twice and the second call happens before the first call
++ * deadline, the work will rescheduled for the second deadline and
++ * won't run before that.
++ *
++ * wiphy_delayed_work_pending() can be used to detect if calling
++ * wiphy_work_delayed_work_queue() would start a new work schedule
++ * or delayed a previous one. As seen below it cannot be used to
++ * detect precisely if the work has finished to execute nor if it
++ * is currently executing.
++ *
++ *      CPU0                                CPU1
++ * wiphy_delayed_work_queue(wk)
++ *  mod_timer(wk->timer)
++ *                                     wiphy_delayed_work_pending(wk) -> true
++ *
++ * [...]
++ * expire_timers(wk->timer)
++ *  detach_timer(wk->timer)
++ *                                     wiphy_delayed_work_pending(wk) -> false
++ *  wk->timer->function()                          |
++ *   wiphy_work_queue(wk)                          | delayed work pending
++ *    list_add_tail()                              | returns false but
++ *    queue_work(cfg80211_wiphy_work)              | wk->func() has not
++ *                                                 | been run yet
++ * [...]                                           |
++ *  cfg80211_wiphy_work()                          |
++ *   wk->func()                                    V
++ *
++ */
++bool wiphy_delayed_work_pending(struct wiphy *wiphy,
++				struct wiphy_delayed_work *dwork);
++
++/**
+  * enum ieee80211_ap_reg_power - regulatory power for an Access Point
+  *
+  * @IEEE80211_REG_UNSET_AP: Access Point has no regulatory power mode
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -1735,6 +1735,13 @@ void wiphy_delayed_work_flush(struct wip
+ }
+ EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
+ 
++bool wiphy_delayed_work_pending(struct wiphy *wiphy,
++				struct wiphy_delayed_work *dwork)
++{
++	return timer_pending(&dwork->timer);
++}
++EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
++
+ static int __init cfg80211_init(void)
+ {
+ 	int err;
diff --git a/package/kernel/mac80211/patches/subsys/366-wifi-mac80211-Convert-color-collision-detection-to-w.patch b/package/kernel/mac80211/patches/subsys/366-wifi-mac80211-Convert-color-collision-detection-to-w.patch
new file mode 100644
index 0000000000..ae72441c46
--- /dev/null
+++ b/package/kernel/mac80211/patches/subsys/366-wifi-mac80211-Convert-color-collision-detection-to-w.patch
@@ -0,0 +1,148 @@
+From: Remi Pommarel <repk at triplefau.lt>
+Date: Tue, 24 Sep 2024 21:28:05 +0200
+Subject: [PATCH] wifi: mac80211: Convert color collision detection to wiphy
+ work
+
+Call to ieee80211_color_collision_detection_work() needs wiphy lock to
+be held (see lockdep assert in cfg80211_bss_color_notify()). Not locking
+wiphy causes the following lockdep error:
+
+  WARNING: CPU: 2 PID: 42 at net/wireless/nl80211.c:19505 cfg80211_bss_color_notify+0x1a4/0x25c
+  Modules linked in:
+  CPU: 2 PID: 42 Comm: kworker/u8:3 Tainted: G        W          6.4.0-02327-g36c6cb260481 #1048
+  Hardware name:
+  Workqueue: phy1 ieee80211_color_collision_detection_work
+  pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
+  pc : cfg80211_bss_color_notify+0x1a4/0x25c
+  lr : cfg80211_bss_color_notify+0x1a0/0x25c
+  sp : ffff000002947d00
+  x29: ffff000002947d00 x28: ffff800008e1a000 x27: ffff000002bd4705
+  x26: ffff00000d034000 x25: ffff80000903cf40 x24: 0000000000000000
+  x23: ffff00000cb70720 x22: 0000000000800000 x21: ffff800008dfb008
+  x20: 000000000000008d x19: ffff00000d035fa8 x18: 0000000000000010
+  x17: 0000000000000001 x16: 000003564b1ce96a x15: 000d69696d057970
+  x14: 000000000000003b x13: 0000000000000001 x12: 0000000000040000
+  x11: 0000000000000001 x10: ffff80000978f9c0 x9 : ffff0000028d3174
+  x8 : ffff800008e30000 x7 : 0000000000000000 x6 : 0000000000000028
+  x5 : 000000000002f498 x4 : ffff00000d034a80 x3 : 0000000000800000
+  x2 : ffff800016143000 x1 : 0000000000000000 x0 : 0000000000000000
+  Call trace:
+   cfg80211_bss_color_notify+0x1a4/0x25c
+   ieee80211_color_collision_detection_work+0x20/0x118
+   process_one_work+0x294/0x554
+   worker_thread+0x70/0x440
+   kthread+0xf4/0xf8
+   ret_from_fork+0x10/0x20
+  irq event stamp: 77372
+  hardirqs last  enabled at (77371): [<ffff800008a346fc>] _raw_spin_unlock_irq+0x2c/0x4c
+  hardirqs last disabled at (77372): [<ffff800008a28754>] el1_dbg+0x20/0x48
+  softirqs last  enabled at (77350): [<ffff8000089e120c>] batadv_send_outstanding_bcast_packet+0xb8/0x120
+  softirqs last disabled at (77348): [<ffff8000089e11d4>] batadv_send_outstanding_bcast_packet+0x80/0x120
+
+The wiphy lock cannot be taken directly from color collision detection
+delayed work (ieee80211_color_collision_detection_work()) because this
+work is cancel_delayed_work_sync() under this wiphy lock causing a
+potential deadlock( see [0] for details).
+
+To fix that ieee80211_color_collision_detection_work() could be
+converted to a wiphy work and cancel_delayed_work_sync() can be simply
+replaced by wiphy_delayed_work_cancel() serving the same purpose under
+wiphy lock.
+
+This could potentially fix [1].
+
+[0]: https://lore.kernel.org/linux-wireless/D4A40Q44OAY2.W3SIF6UEPBUN@freebox.fr/
+[1]: https://lore.kernel.org/lkml/000000000000612f290618eee3e5@google.com/
+
+Reported-by: Nicolas Escande <nescande at freebox.fr>
+Signed-off-by: Remi Pommarel <repk at triplefau.lt>
+Link: https://patch.msgid.link/20240924192805.13859-3-repk@triplefau.lt
+Signed-off-by: Johannes Berg <johannes.berg at intel.com>
+---
+
+--- a/net/mac80211/cfg.c
++++ b/net/mac80211/cfg.c
+@@ -4836,12 +4836,12 @@ void ieee80211_color_change_finalize_wor
+ 	ieee80211_color_change_finalize(link);
+ }
+ 
+-void ieee80211_color_collision_detection_work(struct work_struct *work)
++void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
++					      struct wiphy_work *work)
+ {
+-	struct delayed_work *delayed_work = to_delayed_work(work);
+ 	struct ieee80211_link_data *link =
+-		container_of(delayed_work, struct ieee80211_link_data,
+-			     color_collision_detect_work);
++		container_of(work, struct ieee80211_link_data,
++			     color_collision_detect_work.work);
+ 	struct ieee80211_sub_if_data *sdata = link->sdata;
+ 
+ 	cfg80211_obss_color_collision_notify(sdata->dev, link->color_bitmap,
+@@ -4894,7 +4894,8 @@ ieee80211_obss_color_collision_notify(st
+ 		return;
+ 	}
+ 
+-	if (delayed_work_pending(&link->color_collision_detect_work)) {
++	if (wiphy_delayed_work_pending(sdata->local->hw.wiphy,
++				       &link->color_collision_detect_work)) {
+ 		rcu_read_unlock();
+ 		return;
+ 	}
+@@ -4903,9 +4904,9 @@ ieee80211_obss_color_collision_notify(st
+ 	/* queue the color collision detection event every 500 ms in order to
+ 	 * avoid sending too much netlink messages to userspace.
+ 	 */
+-	ieee80211_queue_delayed_work(&sdata->local->hw,
+-				     &link->color_collision_detect_work,
+-				     msecs_to_jiffies(500));
++	wiphy_delayed_work_queue(sdata->local->hw.wiphy,
++				 &link->color_collision_detect_work,
++				 msecs_to_jiffies(500));
+ 
+ 	rcu_read_unlock();
+ }
+--- a/net/mac80211/ieee80211_i.h
++++ b/net/mac80211/ieee80211_i.h
+@@ -1056,7 +1056,7 @@ struct ieee80211_link_data {
+ 	} csa;
+ 
+ 	struct wiphy_work color_change_finalize_work;
+-	struct delayed_work color_collision_detect_work;
++	struct wiphy_delayed_work color_collision_detect_work;
+ 	u64 color_bitmap;
+ 
+ 	/* context reservation -- protected with wiphy mutex */
+@@ -2010,7 +2010,8 @@ int ieee80211_channel_switch(struct wiph
+ /* color change handling */
+ void ieee80211_color_change_finalize_work(struct wiphy *wiphy,
+ 					  struct wiphy_work *work);
+-void ieee80211_color_collision_detection_work(struct work_struct *work);
++void ieee80211_color_collision_detection_work(struct wiphy *wiphy,
++					      struct wiphy_work *work);
+ 
+ /* interface handling */
+ #define MAC80211_SUPPORTED_FEATURES_TX	(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | \
+--- a/net/mac80211/link.c
++++ b/net/mac80211/link.c
+@@ -41,8 +41,8 @@ void ieee80211_link_init(struct ieee8021
+ 			ieee80211_csa_finalize_work);
+ 	wiphy_work_init(&link->color_change_finalize_work,
+ 			ieee80211_color_change_finalize_work);
+-	INIT_DELAYED_WORK(&link->color_collision_detect_work,
+-			  ieee80211_color_collision_detection_work);
++	wiphy_delayed_work_init(&link->color_collision_detect_work,
++				ieee80211_color_collision_detection_work);
+ 	INIT_LIST_HEAD(&link->assigned_chanctx_list);
+ 	INIT_LIST_HEAD(&link->reserved_chanctx_list);
+ 	wiphy_delayed_work_init(&link->dfs_cac_timer_work,
+@@ -72,7 +72,8 @@ void ieee80211_link_stop(struct ieee8021
+ 	if (link->sdata->vif.type == NL80211_IFTYPE_STATION)
+ 		ieee80211_mgd_stop_link(link);
+ 
+-	cancel_delayed_work_sync(&link->color_collision_detect_work);
++	wiphy_delayed_work_cancel(link->sdata->local->hw.wiphy,
++				  &link->color_collision_detect_work);
+ 	wiphy_work_cancel(link->sdata->local->hw.wiphy,
+ 			  &link->color_change_finalize_work);
+ 	wiphy_work_cancel(link->sdata->local->hw.wiphy,




More information about the lede-commits mailing list