Skip to content

Commit 585eb0d

Browse files
committed
mac80211: backport some upstream fixes
Fix various issues, including potential crashes Signed-off-by: Felix Fietkau <[email protected]> (cherry picked from commit 53eab61)
1 parent 2d465fb commit 585eb0d

6 files changed

+403
-0
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
From: Felix Fietkau <[email protected]>
2+
Date: Fri, 15 Nov 2024 12:28:43 +0100
3+
Subject: [PATCH] wifi: mac80211: fix vif addr when switching from monitor
4+
to station
5+
6+
Since adding support for opting out of virtual monitor support, a zero vif
7+
addr was used to indicate passive vs active monitor to the driver.
8+
This would break the vif->addr when changing the netdev mac address before
9+
switching the interface from monitor to sta mode.
10+
Fix the regression by adding a separate flag to indicate whether vif->addr
11+
is valid.
12+
13+
Reported-by: [email protected]
14+
Fixes: 9d40f7e32774 ("wifi: mac80211: add flag to opt out of virtual monitor support")
15+
Signed-off-by: Felix Fietkau <[email protected]>
16+
---
17+
18+
--- a/include/net/mac80211.h
19+
+++ b/include/net/mac80211.h
20+
@@ -1972,6 +1972,8 @@ enum ieee80211_neg_ttlm_res {
21+
* @neg_ttlm: negotiated TID to link mapping info.
22+
* see &struct ieee80211_neg_ttlm.
23+
* @addr: address of this interface
24+
+ * @addr_valid: indicates if the address is actively used. Set to false for
25+
+ * passive monitor interfaces, true in all other cases.
26+
* @p2p: indicates whether this AP or STA interface is a p2p
27+
* interface, i.e. a GO or p2p-sta respectively
28+
* @netdev_features: tx netdev features supported by the hardware for this
29+
@@ -2011,6 +2013,7 @@ struct ieee80211_vif {
30+
u16 valid_links, active_links, dormant_links, suspended_links;
31+
struct ieee80211_neg_ttlm neg_ttlm;
32+
u8 addr[ETH_ALEN] __aligned(2);
33+
+ bool addr_valid;
34+
bool p2p;
35+
36+
u8 cab_queue;
37+
--- a/net/mac80211/iface.c
38+
+++ b/net/mac80211/iface.c
39+
@@ -279,13 +279,8 @@ static int _ieee80211_change_mac(struct
40+
ret = eth_mac_addr(sdata->dev, sa);
41+
42+
if (ret == 0) {
43+
- if (check_dup) {
44+
- memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
45+
- ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
46+
- } else {
47+
- memset(sdata->vif.addr, 0, ETH_ALEN);
48+
- memset(sdata->vif.bss_conf.addr, 0, ETH_ALEN);
49+
- }
50+
+ memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
51+
+ ether_addr_copy(sdata->vif.bss_conf.addr, sdata->vif.addr);
52+
}
53+
54+
/* Regardless of eth_mac_addr() return we still want to add the
55+
@@ -1324,6 +1319,8 @@ int ieee80211_do_open(struct wireless_de
56+
}
57+
}
58+
59+
+ sdata->vif.addr_valid = sdata->vif.type != NL80211_IFTYPE_MONITOR ||
60+
+ (sdata->u.mntr.flags & MONITOR_FLAG_ACTIVE);
61+
switch (sdata->vif.type) {
62+
case NL80211_IFTYPE_AP_VLAN:
63+
/* no need to tell driver, but set carrier and chanctx */
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
From: Benjamin Lin <[email protected]>
2+
Date: Mon, 18 Nov 2024 16:07:22 +0800
3+
Subject: [PATCH] wifi: mac80211: fix incorrect timing to initialize
4+
station NSS capability
5+
6+
Station's spatial streaming capability should be initialized before
7+
handling VHT OMN, because the handling requires the capability information.
8+
9+
Fixes: a8bca3e9371d ("wifi: mac80211: track capability/opmode NSS separately")
10+
Signed-off-by: Benjamin Lin <[email protected]>
11+
---
12+
13+
--- a/net/mac80211/cfg.c
14+
+++ b/net/mac80211/cfg.c
15+
@@ -1914,6 +1914,8 @@ static int sta_link_apply_parameters(str
16+
params->eht_capa_len,
17+
link_sta);
18+
19+
+ ieee80211_sta_init_nss(link_sta);
20+
+
21+
if (params->opmode_notif_used) {
22+
/* returned value is only needed for rc update, but the
23+
* rc isn't initialized here yet, so ignore it
24+
@@ -1923,8 +1925,6 @@ static int sta_link_apply_parameters(str
25+
sband->band);
26+
}
27+
28+
- ieee80211_sta_init_nss(link_sta);
29+
-
30+
return 0;
31+
}
32+
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
From: "Gustavo A. R. Silva" <[email protected]>
2+
Date: Fri, 25 Oct 2024 16:05:50 -0600
3+
Subject: [PATCH] wifi: mac80211: ieee80211_i: Fix memory corruption bug in
4+
struct ieee80211_chanctx
5+
6+
Move the `struct ieee80211_chanctx_conf conf` to the end of
7+
`struct ieee80211_chanctx` and fix a memory corruption bug
8+
triggered e.g. in `hwsim_set_chanctx_magic()`: `radar_detected`
9+
is being overwritten when `cp->magic = HWSIM_CHANCTX_MAGIC;`
10+
See the function call sequence below:
11+
12+
drv_add_chanctx(... struct ieee80211_chanctx *ctx) ->
13+
local->ops->add_chanctx(&local->hw, &ctx->conf) ->
14+
mac80211_hwsim_add_chanctx(... struct ieee80211_chanctx_conf *ctx) ->
15+
hwsim_set_chanctx_magic(ctx)
16+
17+
This also happens in a number of other drivers.
18+
19+
Also, add a code comment to try to prevent people from introducing
20+
new members after `struct ieee80211_chanctx_conf conf`. Notice that
21+
`struct ieee80211_chanctx_conf` is a flexible structure --a structure
22+
that contains a flexible-array member, so it should always be at
23+
the end of any other containing structures.
24+
25+
This change also fixes 50 of the following warnings:
26+
27+
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]
28+
29+
-Wflex-array-member-not-at-end was introduced in GCC-14, and we are
30+
getting ready to enable it, globally.
31+
32+
Fixes: bca8bc0399ac ("wifi: mac80211: handle ieee80211_radar_detected() for MLO")
33+
Signed-off-by: Gustavo A. R. Silva <[email protected]>
34+
Link: https://patch.msgid.link/ZxwWPrncTeSi1UTq@kspp
35+
[also refer to other drivers in commit message]
36+
Signed-off-by: Johannes Berg <[email protected]>
37+
---
38+
39+
--- a/net/mac80211/ieee80211_i.h
40+
+++ b/net/mac80211/ieee80211_i.h
41+
@@ -894,9 +894,10 @@ struct ieee80211_chanctx {
42+
/* temporary data for search algorithm etc. */
43+
struct ieee80211_chan_req req;
44+
45+
- struct ieee80211_chanctx_conf conf;
46+
-
47+
bool radar_detected;
48+
+
49+
+ /* MUST be last - ends in a flexible-array member. */
50+
+ struct ieee80211_chanctx_conf conf;
51+
};
52+
53+
struct mac80211_qos_map {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
From: Ben Greear <[email protected]>
2+
Date: Thu, 10 Oct 2024 13:39:54 -0700
3+
Subject: [PATCH] mac80211: fix user-power when emulating chanctx
4+
5+
ieee80211_calc_hw_conf_chan was ignoring the configured
6+
user_txpower. If it is set, use it to potentially decrease
7+
txpower as requested.
8+
9+
Signed-off-by: Ben Greear <[email protected]>
10+
Link: https://patch.msgid.link/[email protected]
11+
Signed-off-by: Johannes Berg <[email protected]>
12+
---
13+
14+
--- a/net/mac80211/main.c
15+
+++ b/net/mac80211/main.c
16+
@@ -167,6 +167,8 @@ static u32 ieee80211_calc_hw_conf_chan(s
17+
}
18+
19+
power = ieee80211_chandef_max_power(&chandef);
20+
+ if (local->user_power_level != IEEE80211_UNSET_POWER_LEVEL)
21+
+ power = min(local->user_power_level, power);
22+
23+
rcu_read_lock();
24+
list_for_each_entry_rcu(sdata, &local->interfaces, list) {
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
From: Remi Pommarel <[email protected]>
2+
Date: Tue, 24 Sep 2024 21:28:04 +0200
3+
Subject: [PATCH] wifi: cfg80211: Add wiphy_delayed_work_pending()
4+
5+
Add wiphy_delayed_work_pending() to check if any delayed work timer is
6+
pending, that can be used to be sure that wiphy_delayed_work_queue()
7+
won't postpone an already pending delayed work.
8+
9+
Signed-off-by: Remi Pommarel <[email protected]>
10+
Link: https://patch.msgid.link/[email protected]
11+
[fix return value kernel-doc]
12+
Signed-off-by: Johannes Berg <[email protected]>
13+
---
14+
15+
--- a/include/net/cfg80211.h
16+
+++ b/include/net/cfg80211.h
17+
@@ -6141,6 +6141,50 @@ void wiphy_delayed_work_flush(struct wip
18+
struct wiphy_delayed_work *dwork);
19+
20+
/**
21+
+ * wiphy_delayed_work_pending - Find out whether a wiphy delayable
22+
+ * work item is currently pending.
23+
+ *
24+
+ * @wiphy: the wiphy, for debug purposes
25+
+ * @dwork: the delayed work in question
26+
+ *
27+
+ * Return: true if timer is pending, false otherwise
28+
+ *
29+
+ * How wiphy_delayed_work_queue() works is by setting a timer which
30+
+ * when it expires calls wiphy_work_queue() to queue the wiphy work.
31+
+ * Because wiphy_delayed_work_queue() uses mod_timer(), if it is
32+
+ * called twice and the second call happens before the first call
33+
+ * deadline, the work will rescheduled for the second deadline and
34+
+ * won't run before that.
35+
+ *
36+
+ * wiphy_delayed_work_pending() can be used to detect if calling
37+
+ * wiphy_work_delayed_work_queue() would start a new work schedule
38+
+ * or delayed a previous one. As seen below it cannot be used to
39+
+ * detect precisely if the work has finished to execute nor if it
40+
+ * is currently executing.
41+
+ *
42+
+ * CPU0 CPU1
43+
+ * wiphy_delayed_work_queue(wk)
44+
+ * mod_timer(wk->timer)
45+
+ * wiphy_delayed_work_pending(wk) -> true
46+
+ *
47+
+ * [...]
48+
+ * expire_timers(wk->timer)
49+
+ * detach_timer(wk->timer)
50+
+ * wiphy_delayed_work_pending(wk) -> false
51+
+ * wk->timer->function() |
52+
+ * wiphy_work_queue(wk) | delayed work pending
53+
+ * list_add_tail() | returns false but
54+
+ * queue_work(cfg80211_wiphy_work) | wk->func() has not
55+
+ * | been run yet
56+
+ * [...] |
57+
+ * cfg80211_wiphy_work() |
58+
+ * wk->func() V
59+
+ *
60+
+ */
61+
+bool wiphy_delayed_work_pending(struct wiphy *wiphy,
62+
+ struct wiphy_delayed_work *dwork);
63+
+
64+
+/**
65+
* enum ieee80211_ap_reg_power - regulatory power for an Access Point
66+
*
67+
* @IEEE80211_REG_UNSET_AP: Access Point has no regulatory power mode
68+
--- a/net/wireless/core.c
69+
+++ b/net/wireless/core.c
70+
@@ -1735,6 +1735,13 @@ void wiphy_delayed_work_flush(struct wip
71+
}
72+
EXPORT_SYMBOL_GPL(wiphy_delayed_work_flush);
73+
74+
+bool wiphy_delayed_work_pending(struct wiphy *wiphy,
75+
+ struct wiphy_delayed_work *dwork)
76+
+{
77+
+ return timer_pending(&dwork->timer);
78+
+}
79+
+EXPORT_SYMBOL_GPL(wiphy_delayed_work_pending);
80+
+
81+
static int __init cfg80211_init(void)
82+
{
83+
int err;

0 commit comments

Comments
 (0)