FAILED: patch "[PATCH] wifi: mac80211: count only matching reservations in reserved" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-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.18.y
git checkout FETCH_HEAD
git cherry-pick -x 437f3727b4fd715266c296435c116288f82666fd
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100534-sector-drab-5350@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 437f3727b4fd715266c296435c116288f82666fd Mon Sep 17 00:00:00 2001
From: Zhiling Zou <[email protected]>
Date: Mon, 3 Aug 2026 11:28:22 +0800
Subject: [PATCH] wifi: mac80211: count only matching reservations in reserved
switch
ieee80211_vif_use_reserved_switch() validates a replacement by counting assigned links on ctx->replace_ctx and treating reservations too broadly. A link can still be assigned to the old channel context while holding a reservation that belongs to a different replacement operation.
That can make the current replacement appear complete too early. If another link finalizes first, the function can free the WILL_BE_REPLACED chanctx while the unmatched link and driver still use it, leading to a use-after-free in later beacon generation.
Require an in-place reservation to point at the current replacement context, and require the reserved and assigned contexts to be the matching replacement pair, before counting or moving the link.
net/mac80211/chan.c +23 -7
@@ -1772,7 +1772,8 @@ ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link) }static bool -ieee80211_link_has_in_place_reservation (struct ieee80211_link_data *link) +ieee80211_link_has_in_place_reservation (struct ieee80211_link_data *link, +struct ieee80211_chanctx *ctx) {struct ieee80211_sub_if_data *sdata = link->sdata;struct ieee80211_chanctx *old_ctx, *new_ctx;
@@ -1782,6 +1783,9 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link) new_ctx = link->reserved_chanctx; old_ctx =ieee80211_link_get_chanctx (link); +if (new_ctx != ctx) +return false; +if (!old_ctx)return false;
@@ -1794,6 +1798,12 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)if (new_ctx->replace_state !=IEEE80211_CHANCTX_REPLACES_OTHER )return false; +if (new_ctx->replace_ctx != old_ctx) +return false; + +if (old_ctx->replace_ctx != new_ctx) +return false; +return true; }
@@ -1823,7 +1833,8 @@ static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local, }for_each_chanctx_user_reserved (local, ctx, &iter) { -if (!ieee80211_link_has_in_place_reservation (iter.link)) +if (!ieee80211_link_has_in_place_reservation (iter.link, + ctx))continue ; old_ctx =ieee80211_link_get_chanctx (iter.link);
@@ -1925,7 +1936,9 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)for_each_chanctx_user_assigned (local, ctx->replace_ctx, &iter) { n_assigned++; -if (iter.link && iter.link->reserved_chanctx) { +if (iter.link && +ieee80211_link_has_in_place_reservation (iter.link, + ctx)) { n_reserved++;if (iter.link->reserved_ready) n_ready++;
@@ -1950,7 +1963,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) use_reserved: ctx->conf.radar_enabled = false;for_each_chanctx_user_reserved (local, ctx, &iter) { -if (ieee80211_link_has_in_place_reservation (iter.link) && +if (ieee80211_link_has_in_place_reservation (iter.link, + ctx) && !iter.link->reserved_ready)return -EAGAIN ;
@@ -1991,7 +2005,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) }for_each_chanctx_user_reserved (local, ctx, &iter) { -if (!ieee80211_link_has_in_place_reservation (iter.link)) +if (!ieee80211_link_has_in_place_reservation (iter.link, + ctx))continue ; ieee80211_chan_bw_change(local,
@@ -2040,7 +2055,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)struct ieee80211_bss_conf *link_conf = link->conf;u64 changed =0 ; -if (!ieee80211_link_has_in_place_reservation (link)) +if (!ieee80211_link_has_in_place_reservation (link, ctx))continue ; rcu_assign_pointer(link_conf->chanctx_conf,
@@ -2091,7 +2106,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)for_each_chanctx_user_reserved (local, ctx, &iter) {struct ieee80211_link_data *link = iter.link; -if (WARN_ON (ieee80211_link_has_in_place_reservation (link))) +if (WARN_ON (ieee80211_link_has_in_place_reservation (link, + ctx)))continue ;if (!link->reserved_ready)
Sasha Levin
maintainerPATCH 1/1 wifi: mac80211: count only matching reservations in reserved switch
From: Zhiling Zou <[email protected]>
[ Upstream commit 437f3727b4fd715266c296435c116288f82666fd ]
ieee80211_vif_use_reserved_switch() validates a replacement by counting assigned links on ctx->replace_ctx and treating reservations too broadly. A link can still be assigned to the old channel context while holding a reservation that belongs to a different replacement operation.
That can make the current replacement appear complete too early. If another link finalizes first, the function can free the WILL_BE_REPLACED chanctx while the unmatched link and driver still use it, leading to a use-after-free in later beacon generation.
Require an in-place reservation to point at the current replacement context, and require the reserved and assigned contexts to be the matching replacement pair, before counting or moving the link.
--- net/mac80211/chan.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-)
net/mac80211/chan.c +18 -7
@@ -1485,7 +1485,8 @@ ieee80211_link_use_reserved_assign(struct ieee80211_link_data *link) }static bool -ieee80211_link_has_in_place_reservation (struct ieee80211_link_data *link) +ieee80211_link_has_in_place_reservation (struct ieee80211_link_data *link, +struct ieee80211_chanctx *ctx) {struct ieee80211_sub_if_data *sdata = link->sdata;struct ieee80211_chanctx *old_ctx, *new_ctx;
@@ -1495,6 +1496,9 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link) new_ctx = link->reserved_chanctx; old_ctx =ieee80211_link_get_chanctx (link); +if (new_ctx != ctx) +return false; +if (!old_ctx)return false;
@@ -1507,6 +1511,12 @@ ieee80211_link_has_in_place_reservation(struct ieee80211_link_data *link)if (new_ctx->replace_state !=IEEE80211_CHANCTX_REPLACES_OTHER )return false; +if (new_ctx->replace_ctx != old_ctx) +return false; + +if (old_ctx->replace_ctx != new_ctx) +return false; +return true; }
@@ -1536,7 +1546,7 @@ static int ieee80211_chsw_switch_vifs(struct ieee80211_local *local,list_for_each_entry (link, &ctx->reserved_links, reserved_chanctx_list) { -if (!ieee80211_link_has_in_place_reservation (link)) +if (!ieee80211_link_has_in_place_reservation (link, ctx))continue ; old_ctx =ieee80211_link_get_chanctx (link);
@@ -1639,7 +1649,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)list_for_each_entry (link, &ctx->replace_ctx->assigned_links, assigned_chanctx_list) { n_assigned++; -if (link->reserved_chanctx) { +if (ieee80211_link_has_in_place_reservation (link, ctx)) { n_reserved++;if (link->reserved_ready) n_ready++;
@@ -1660,7 +1670,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local) ctx->conf.radar_enabled = false;list_for_each_entry (link, &ctx->reserved_links, reserved_chanctx_list) { -if (ieee80211_link_has_in_place_reservation (link) && +if (ieee80211_link_has_in_place_reservation (link, ctx) && !link->reserved_ready)return -EAGAIN ;
@@ -1702,7 +1712,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)list_for_each_entry (link, &ctx->reserved_links, reserved_chanctx_list) { -if (!ieee80211_link_has_in_place_reservation (link)) +if (!ieee80211_link_has_in_place_reservation (link, ctx))continue ; ieee80211_chan_bw_change(local,
@@ -1751,7 +1761,7 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)struct ieee80211_bss_conf *link_conf = link->conf;u64 changed =0 ; -if (!ieee80211_link_has_in_place_reservation (link)) +if (!ieee80211_link_has_in_place_reservation (link, ctx))continue ; rcu_assign_pointer(link_conf->chanctx_conf,
@@ -1805,7 +1815,8 @@ static int ieee80211_vif_use_reserved_switch(struct ieee80211_local *local)*/ list_for_each_entry_safe (link, link_tmp, &ctx->reserved_links, reserved_chanctx_list) { -if (WARN_ON (ieee80211_link_has_in_place_reservation (link))) +if (WARN_ON (ieee80211_link_has_in_place_reservation (link, + ctx)))continue ;if (WARN_ON (link->reserved_chanctx != ctx))
Signature · 1 line
2.53.0