Skip to content

Commit c90b93b

Browse files
committed
wifi: cfg80211: update hidden BSSes to avoid WARN_ON
When updating beacon elements in a non-transmitted BSS, also update the hidden sub-entries to the same beacon elements, so that a future update through other paths won't trigger a WARN_ON(). The warning is triggered because the beacon elements in the hidden BSSes that are children of the BSS should always be the same as in the parent. Reported-by: Sönke Huster <[email protected]> Tested-by: Sönke Huster <[email protected]> Fixes: 0b8fb82 ("cfg80211: Parsing of Multiple BSSID information in scanning") Signed-off-by: Johannes Berg <[email protected]>
1 parent b2d03ca commit c90b93b

File tree

1 file changed

+20
-11
lines changed

1 file changed

+20
-11
lines changed

net/wireless/scan.c

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,23 @@ struct cfg80211_non_tx_bss {
16071607
u8 bssid_index;
16081608
};
16091609

1610+
static void cfg80211_update_hidden_bsses(struct cfg80211_internal_bss *known,
1611+
const struct cfg80211_bss_ies *new_ies,
1612+
const struct cfg80211_bss_ies *old_ies)
1613+
{
1614+
struct cfg80211_internal_bss *bss;
1615+
1616+
/* Assign beacon IEs to all sub entries */
1617+
list_for_each_entry(bss, &known->hidden_list, hidden_list) {
1618+
const struct cfg80211_bss_ies *ies;
1619+
1620+
ies = rcu_access_pointer(bss->pub.beacon_ies);
1621+
WARN_ON(ies != old_ies);
1622+
1623+
rcu_assign_pointer(bss->pub.beacon_ies, new_ies);
1624+
}
1625+
}
1626+
16101627
static bool
16111628
cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
16121629
struct cfg80211_internal_bss *known,
@@ -1630,7 +1647,6 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
16301647
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
16311648
} else if (rcu_access_pointer(new->pub.beacon_ies)) {
16321649
const struct cfg80211_bss_ies *old;
1633-
struct cfg80211_internal_bss *bss;
16341650

16351651
if (known->pub.hidden_beacon_bss &&
16361652
!list_empty(&known->hidden_list)) {
@@ -1658,16 +1674,7 @@ cfg80211_update_known_bss(struct cfg80211_registered_device *rdev,
16581674
if (old == rcu_access_pointer(known->pub.ies))
16591675
rcu_assign_pointer(known->pub.ies, new->pub.beacon_ies);
16601676

1661-
/* Assign beacon IEs to all sub entries */
1662-
list_for_each_entry(bss, &known->hidden_list, hidden_list) {
1663-
const struct cfg80211_bss_ies *ies;
1664-
1665-
ies = rcu_access_pointer(bss->pub.beacon_ies);
1666-
WARN_ON(ies != old);
1667-
1668-
rcu_assign_pointer(bss->pub.beacon_ies,
1669-
new->pub.beacon_ies);
1670-
}
1677+
cfg80211_update_hidden_bsses(known, new->pub.beacon_ies, old);
16711678

16721679
if (old)
16731680
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);
@@ -2360,6 +2367,8 @@ cfg80211_update_notlisted_nontrans(struct wiphy *wiphy,
23602367
} else {
23612368
old = rcu_access_pointer(nontrans_bss->beacon_ies);
23622369
rcu_assign_pointer(nontrans_bss->beacon_ies, new_ies);
2370+
cfg80211_update_hidden_bsses(bss_from_pub(nontrans_bss),
2371+
new_ies, old);
23632372
rcu_assign_pointer(nontrans_bss->ies, new_ies);
23642373
if (old)
23652374
kfree_rcu((struct cfg80211_bss_ies *)old, rcu_head);

0 commit comments

Comments
 (0)