forked from marfrit/kernel-agent
b04c8cd501
PR #33's per-series mirrors were generated against the bes2600-dkms cleanups branch (rooted at fe73571) without rebasing onto the v7.0-danctnix1 kernel baseline. Result: per-commit diffs carried stale baseline context (e.g. from_timer rather than the new timer_container_of API), so the cumulative no longer applied cleanly to ohm's actual base. pkgrel=6 build #1 failed with 'Hunk #3 FAILED' in Patch D's sta.c. Fix: in marfrit/bes2600-dkms, create danctnix-sync branch (fe73571 + drop-in replace bes2600/ with v7.0-danctnix1's drivers/staging/bes2600/), rebase cleanups onto it as cleanups-rebased-on-danctnix, manually resolve the resulting conflicts keeping each commit's intent + the new baseline context, rebase Patch H accordingly. Format-patch and re-route to the same series-dir names as PR #33. Conflict resolution notes: - 'remove userspace /dev/bes2600 character device interface' commit: the chardev wrapper was removed but two utility funcs that danctnix's bes2600_btuart.c depends on (bes2600_chrdev_is_bus_error, bes2600_chrdev_switch_subsys_glb) were re-added with EXPORT_SYMBOL_GPL. bes2600_switch_bt re-added as static (file-local, called only from bes2600_chrdev_switch_subsys_glb). - Patch D (atomicize ba_lock): re-resolved bes2600_ba_timer's timer_container_of() vs from_timer() to keep the new API. - SCS Makefile @@ hunk counts corrected from -9,6 +9,10 to -9,6 +9,11 (the original was actually wrong; build-via-fuzz was masking it). Cumulative b2sum: ka-promote ohm now emits eb179c03f35a4dbaec2e40036f0033ef04985bb6b14ab22419d68e5caaa5874f... (279 554 bytes, 32 patches resolved). pkgrel=6 built from this manifest + installed on ohm 2026-05-19 ~23:39. Functional verification: bes2600 + bes2600_btuart both load, Pattern A 0 over fresh boot, wlan0 associates to newton. srcversion 1A919EED0E6DC2478559B17 differs from pkgrel=5's BEB625FA... — the reconstruction is functionally equivalent (5 GHz working, no firmware/driver race conditions) but NOT byte-equivalent (the chardev utility re-add chose different formatting than the original danctnix code). Byte-equivalence is not a goal; per-series traceability and working hardware are. Closes (proper this time): #29. Refs: #28, #30, #33 (the half-working attempt), #31, #32.
145 lines
4.4 KiB
Diff
145 lines
4.4 KiB
Diff
From d9e6361cf0c273f07aee94f24533a5f19e7ed4c0 Mon Sep 17 00:00:00 2001
|
|
From: Markus Fritsche <fritsche.markus@gmail.com>
|
|
Date: Thu, 7 May 2026 21:24:01 +0200
|
|
Subject: [PATCH 24/29] bes2600: fix concurrency UAF in bes2600_hw_scan and
|
|
sched_scan
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
bes2600_bss_info_changed() and bes2600_hw_scan() can run concurrently.
|
|
The probe-request SKB allocated by ieee80211_probereq_get() before
|
|
scan.lock + conf_lock are taken can be touched by a concurrent
|
|
bss_info_changed (via wsm_set_template_frame's path) while we hold no
|
|
lock. Reorder to acquire both locks BEFORE the SKB allocation.
|
|
|
|
Also reorder cleanup paths so dev_kfree_skb() runs BEFORE up() —
|
|
otherwise a small window exists where the SKB has been touched but the
|
|
lock has been released, allowing concurrent code to also touch it.
|
|
|
|
Three sites fixed:
|
|
- bes2600_hw_scan: lock-take + ENOMEM cleanup + wsm_set_template_frame
|
|
error cleanup + success-path SKB free + lock release order
|
|
- bes2600_sched_scan_start (#ifdef ROAM_OFFLOAD): same three sub-fixes
|
|
(compiled-out at default build, fixed for consistency)
|
|
- All success/error paths: dev_kfree_skb before up()
|
|
|
|
Backport of cw1200 mainline commit 86760e0dfe36 ("cw1200: Fix
|
|
concurrency use-after-free bugs in cw1200_hw_scan()", 2018-12-14),
|
|
which fixed the identical bug in the same code shape we inherited.
|
|
That commit was merged from upstream 4f68ef64cd7f.
|
|
|
|
Cherry-picked from upstream Linux:
|
|
86760e0dfe36 cw1200: Fix concurrency use-after-free bugs in cw1200_hw_scan()
|
|
Author: Jia-Ju Bai <baijiaju1990@gmail.com>
|
|
Link: https://lore.kernel.org/r/20181214035521.7575-1-baijiaju1990@gmail.com
|
|
---
|
|
bes2600/scan.c | 37 ++++++++++++++++++++++---------------
|
|
1 file changed, 22 insertions(+), 15 deletions(-)
|
|
|
|
diff --git a/drivers/staging/bes2600/scan.c b/drivers/staging/bes2600/scan.c
|
|
index b944adc..3cd7b64 100644
|
|
--- a/drivers/staging/bes2600/scan.c
|
|
+++ b/drivers/staging/bes2600/scan.c
|
|
@@ -257,18 +257,21 @@ int bes2600_hw_scan(struct ieee80211_hw *hw,
|
|
|
|
bes2600_pwr_set_busy_event(hw_priv, BES_PWR_LOCK_ON_SCAN);
|
|
|
|
+ /* will be unlocked in bes2600_scan_work() */
|
|
+ down(&hw_priv->scan.lock);
|
|
+ down(&hw_priv->conf_lock);
|
|
+
|
|
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
|
|
req->ie_len);
|
|
- if (!frame.skb)
|
|
+ if (!frame.skb) {
|
|
+ up(&hw_priv->conf_lock);
|
|
+ up(&hw_priv->scan.lock);
|
|
return -ENOMEM;
|
|
+ }
|
|
|
|
if (req->ie_len)
|
|
skb_put_data(frame.skb, req->ie, req->ie_len);
|
|
|
|
- /* will be unlocked in bes2600_scan_work() */
|
|
- down(&hw_priv->scan.lock);
|
|
- down(&hw_priv->conf_lock);
|
|
-
|
|
if (frame.skb) {
|
|
int ret;
|
|
//if (priv->if_id == 0)
|
|
@@ -286,9 +289,9 @@ int bes2600_hw_scan(struct ieee80211_hw *hw,
|
|
}
|
|
#endif
|
|
if (ret) {
|
|
+ dev_kfree_skb(frame.skb);
|
|
up(&hw_priv->conf_lock);
|
|
up(&hw_priv->scan.lock);
|
|
- dev_kfree_skb(frame.skb);
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -318,10 +321,10 @@ int bes2600_hw_scan(struct ieee80211_hw *hw,
|
|
++hw_priv->scan.n_ssids;
|
|
}
|
|
|
|
- up(&hw_priv->conf_lock);
|
|
-
|
|
if (frame.skb)
|
|
dev_kfree_skb(frame.skb);
|
|
+
|
|
+ up(&hw_priv->conf_lock);
|
|
#ifdef WIFI_BT_COEXIST_EPTA_ENABLE
|
|
bwifi_change_current_status(hw_priv, BWIFI_STATUS_SCANNING);
|
|
#endif
|
|
@@ -362,14 +365,18 @@ int bes2600_hw_sched_scan_start(struct ieee80211_hw *hw,
|
|
if (req->n_ssids > hw->wiphy->max_scan_ssids)
|
|
return -EINVAL;
|
|
|
|
+ /* will be unlocked in bes2600_scan_work() */
|
|
+ down(&hw_priv->scan.lock);
|
|
+ down(&hw_priv->conf_lock);
|
|
+
|
|
frame.skb = ieee80211_probereq_get(hw, priv->vif->addr, NULL, 0,
|
|
req->ie_len);
|
|
- if (!frame.skb)
|
|
+ if (!frame.skb) {
|
|
+ up(&hw_priv->conf_lock);
|
|
+ up(&hw_priv->scan.lock);
|
|
return -ENOMEM;
|
|
+ }
|
|
|
|
- /* will be unlocked in bes2600_scan_work() */
|
|
- down(&hw_priv->scan.lock);
|
|
- down(&hw_priv->conf_lock);
|
|
if (frame.skb) {
|
|
int ret;
|
|
if (priv->if_id == 0)
|
|
@@ -380,9 +387,9 @@ int bes2600_hw_sched_scan_start(struct ieee80211_hw *hw,
|
|
ret = wsm_set_probe_responder(priv, true);
|
|
}
|
|
if (ret) {
|
|
+ dev_kfree_skb(frame.skb);
|
|
up(&hw_priv->conf_lock);
|
|
up(&hw_priv->scan.lock);
|
|
- dev_kfree_skb(frame.skb);
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -414,10 +421,10 @@ int bes2600_hw_sched_scan_start(struct ieee80211_hw *hw,
|
|
}
|
|
}
|
|
|
|
- up(&hw_priv->conf_lock);
|
|
-
|
|
if (frame.skb)
|
|
dev_kfree_skb(frame.skb);
|
|
+
|
|
+ up(&hw_priv->conf_lock);
|
|
queue_work(hw_priv->workqueue, &hw_priv->scan.swork);
|
|
wiphy_warn(hw->wiphy, "<--[SCAN] Scheduled scan request.\n");
|
|
return 0;
|
|
--
|
|
2.54.0
|
|
|