realtek: consistently flood RMA frames
[openwrt/staging/dedeckeh.git] / package / kernel / mac80211 / patches / subsys / 359-wifi-cfg80211-update-hidden-BSSes-to-avoid-WARN_ON.patch
1 From: Johannes Berg <johannes.berg@intel.com>
2 Date: Wed, 5 Oct 2022 23:11:43 +0200
3 Subject: [PATCH] wifi: cfg80211: update hidden BSSes to avoid WARN_ON
4 MIME-Version: 1.0
5 Content-Type: text/plain; charset=UTF-8
6 Content-Transfer-Encoding: 8bit
7
8 commit c90b93b5b782891ebfda49d4e5da36632fefd5d1 upstream.
9
10 When updating beacon elements in a non-transmitted BSS,
11 also update the hidden sub-entries to the same beacon
12 elements, so that a future update through other paths
13 won't trigger a WARN_ON().
14
15 The warning is triggered because the beacon elements in
16 the hidden BSSes that are children of the BSS should
17 always be the same as in the parent.
18
19 Reported-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
20 Tested-by: Sönke Huster <shuster@seemoo.tu-darmstadt.de>
21 Fixes: 0b8fb8235be8 ("cfg80211: Parsing of Multiple BSSID information in scanning")
22 Signed-off-by: Johannes Berg <johannes.berg@intel.com>
23 ---
24
25 --- a/net/wireless/scan.c
26 +++ b/net/wireless/scan.c
27 @@ -1609,6 +1609,23 @@ struct cfg80211_non_tx_bss {
28 u8 bssid_index;
29 };
30
31 +static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
32 + const struct cfg80211_bss_ies *new_ies,
33 + const struct cfg80211_bss_ies *old_ies)
34 +{
35 + struct cfg80211_internal_bss *bss;
36 +
37 + /* Assign beacon IEs to all sub entries */
38 + list_for_each_entry(bss, &known->hidden_list, hidden_list) {
39 + const struct cfg80211_bss_ies *ies;
40 +
41 + ies = rcu_access_pointer(bss->pub.beacon_ies);
42 + WARN_ON(ies != old_ies);
43 +
44 + rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
45 + }
46 +}
47 +
48 static bool
49 cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
50 struct cfg80211_internal_bss *known,
51 @@ -1632,7 +1649,6 @@ cfg80211_update_known_bss(struct cfg8021
52 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
53 } else if (rcu_access_pointer(new->pub.beacon_ies)) {
54 const struct cfg80211_bss_ies *old;
55 - struct cfg80211_internal_bss *bss;
56
57 if (known->pub.hidden_beacon_bss &&
58 !list_empty(&known->hidden_list)) {
59 @@ -1660,16 +1676,7 @@ cfg80211_update_known_bss(struct cfg8021
60 if (old == rcu_access_pointer(known->pub.ies))
61 rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
62
63 - /* Assign beacon IEs to all sub entries */
64 - list_for_each_entry(bss, &known->hidden_list, hidden_list) {
65 - const struct cfg80211_bss_ies *ies;
66 -
67 - ies = rcu_access_pointer(bss->pub.beacon_ies);
68 - WARN_ON(ies != old);
69 -
70 - rcu_assign_pointer(bss->pub.beacon_ies,
71 - new->pub.beacon_ies);
72 - }
73 + cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
74
75 if (old)
76 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
77 @@ -2319,6 +2326,8 @@ cfg80211_update_notlisted_nontrans(struc
78 } else {
79 old = rcu_access_pointer(nontrans_bss->beacon_ies);
80 rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
81 + cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
82 + new_ies, old);
83 rcu_assign_pointer(nontrans_bss->ies, new_ies);
84 if (old)
85 kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);