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