From: Miri Korenblit miriam.rachel.korenblit@intel.com
[ Upstream commit 185cc2352cb1ef2178fe4e9a220a73c94007b8bb ]
In hidden SSID we have separate BSS entries for the beacon and for the probe response(s). The BSS entry time stamps represent the age of the BSS; when was the last time we heard the BSS. When we receive a beacon of a hidden SSID it means that we heard that BSS, so it makes sense to indicate that in the probe response entries. Do that.
Reviewed-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Miri Korenblit miriam.rachel.korenblit@intel.com Link: https://patch.msgid.link/20250907115135.712745e498c0.I38186abf5d20dec6f6f2d4... Signed-off-by: Johannes Berg johannes.berg@intel.com Signed-off-by: Sasha Levin sashal@kernel.org ---
LLM Generated explanations, may be completely bogus:
YES
Explanation - Fixes a real bug: For hidden SSIDs cfg80211 keeps separate BSS entries for the beacon and probe response(s) (see doc comment in net/wireless/scan.c:39). Previously, when only a beacon was received, the probe-response BSS entries’ timestamps were not refreshed, making them appear stale/expired despite the AP being heard. - Precise change: When updating a hidden-SSID group due to a beacon, the patch propagates the current time to all sub-entries: - net/wireless/scan.c:1820 sets `bss->ts = known->ts` - net/wireless/scan.c:1821 sets `bss->pub.ts_boottime = known->pub.ts_boottime` - Correct update ordering: Timestamps for the “known” BSS are updated at the start of the update function so the propagated values are current and also updated even if an early-return path is taken: - net/wireless/scan.c:1889 updates `known->ts` - net/wireless/scan.c:1890 updates `known->pub.ts_boottime` - Early-return case (hidden/beacon confusion) occurs at net/wireless/scan.c:1912 and can now still benefit from timestamp refresh. - Why it matters to users: Expiration and selection logic uses `ts`; stale `ts` causes hidden SSID probe-response entries to be treated as expired: - Expire processing uses `ts` (net/wireless/scan.c:479) - get_bss filters out expired entries with `ts + IEEE80211_SCAN_RESULT_EXPIRE` (net/wireless/scan.c:1634) - Userspace also consumes `ts_boottime` via NL80211_BSS_LAST_SEEN_BOOTTIME (net/wireless/nl80211.c:11573), so keeping it accurate improves reporting. - Small and contained: The patch touches only net/wireless/scan.c and adds 7 lines + minor reordering; no API or architectural changes. - Behaviorally safe: The new behavior aligns with the documented hidden- SSID grouping, i.e., hearing any frame (beacon) from the AP indicates the BSS is alive for the grouped probe-response entries (net/wireless/scan.c:39). If beacons stop, timestamps still age and entries expire as before. - Minimal regression risk: Only timestamp bookkeeping is affected. No changes to element parsing, channel handling, or RCU lifetimes; updates occur under `bss_lock` and mirror existing direct-field updates elsewhere in scan.c. - Stable criteria fit: - Important bugfix: avoids hidden SSID entries being incorrectly aged out, impacting discoverability/connectivity. - Small, localized change with clear intent and low risk. - No new features or architectural changes. - Applies to a common subsystem (cfg80211) with wide user impact.
Conclusion: This is a straightforward correctness fix for hidden-SSID handling and should be backported to stable.
net/wireless/scan.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 6c7b7c3828a41..90a9187a6b135 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c @@ -1816,6 +1816,9 @@ static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known, WARN_ON(ies != old_ies);
rcu_assign_pointer(bss->pub.beacon_ies, new_ies); + + bss->ts = known->ts; + bss->pub.ts_boottime = known->pub.ts_boottime; } }
@@ -1882,6 +1885,10 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, { lockdep_assert_held(&rdev->bss_lock);
+ /* Update time stamps */ + known->ts = new->ts; + known->pub.ts_boottime = new->pub.ts_boottime; + /* Update IEs */ if (rcu_access_pointer(new->pub.proberesp_ies)) { const struct cfg80211_bss_ies *old; @@ -1945,8 +1952,6 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev, if (signal_valid) known->pub.signal = new->pub.signal; known->pub.capability = new->pub.capability; - known->ts = new->ts; - known->pub.ts_boottime = new->pub.ts_boottime; known->parent_tsf = new->parent_tsf; known->pub.chains = new->pub.chains; memcpy(known->pub.chain_signal, new->pub.chain_signal,