git: 49619f73151a - main - net80211: make sure calls to (*iv_update_bss)() are locked

From: Bjoern A. Zeeb <bz_at_FreeBSD.org>
Date: Sat, 03 Feb 2024 13:56:22 UTC
The branch main has been updated by bz:

URL: https://cgit.FreeBSD.org/src/commit/?id=49619f73151aeaca4cef5adf631253da04a46e19

commit 49619f73151aeaca4cef5adf631253da04a46e19
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2024-01-19 14:52:03 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2024-02-03 13:55:29 +0000

    net80211: make sure calls to (*iv_update_bss)() are locked
    
    It turned out thare various calls into (*iv_update_bss)(), that is
    direct changes to vap->iv_bss in the old days, happened without
    synchronisation.
    
    Use locking assertions to document the requirement or status quo
    at some callers given ic locking will eventually have to be dealt
    with.
    
    MFC after:      3 days
    Reviewed by:    cc
    Differential Revision: https://reviews.freebsd.org/D43512
---
 sys/net80211/ieee80211_node.c  | 15 +++++++++++++++
 sys/net80211/ieee80211_proto.c |  2 ++
 2 files changed, 17 insertions(+)

diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c
index f6bb4245f543..8f8dc5f378b8 100644
--- a/sys/net80211/ieee80211_node.c
+++ b/sys/net80211/ieee80211_node.c
@@ -171,6 +171,10 @@ ieee80211_node_vattach(struct ieee80211vap *vap)
 void
 ieee80211_node_latevattach(struct ieee80211vap *vap)
 {
+
+	/* XXX should ieee80211_vap_attach(), our only caller hold the lock? */
+	IEEE80211_UNLOCK_ASSERT(vap->iv_ic);
+
 	if (vap->iv_opmode == IEEE80211_M_HOSTAP) {
 		/* XXX should we allow max aid to be zero? */
 		if (vap->iv_max_aid < IEEE80211_AID_MIN) {
@@ -191,7 +195,9 @@ ieee80211_node_latevattach(struct ieee80211vap *vap)
 		}
 	}
 
+	IEEE80211_LOCK(vap->iv_ic);
 	ieee80211_reset_bss(vap);
+	IEEE80211_UNLOCK(vap->iv_ic);
 
 	vap->iv_auth = ieee80211_authenticator_get(vap->iv_bss->ni_authmode);
 }
@@ -201,11 +207,16 @@ ieee80211_node_vdetach(struct ieee80211vap *vap)
 {
 	struct ieee80211com *ic = vap->iv_ic;
 
+	/* XXX should ieee80211_vap_detach(), our only caller hold the lock? */
+	IEEE80211_UNLOCK_ASSERT(vap->iv_ic);
+
 	ieee80211_node_table_reset(&ic->ic_sta, vap);
+	IEEE80211_LOCK(ic);
 	if (vap->iv_bss != NULL) {
 		ieee80211_free_node(vap->iv_bss);
 		vap->iv_update_bss(vap, NULL);
 	}
+	IEEE80211_UNLOCK(ic);
 	if (vap->iv_aid_bitmap != NULL) {
 		IEEE80211_FREE(vap->iv_aid_bitmap, M_80211_NODE);
 		vap->iv_aid_bitmap = NULL;
@@ -455,6 +466,8 @@ ieee80211_reset_bss(struct ieee80211vap *vap)
 	struct ieee80211com *ic = vap->iv_ic;
 	struct ieee80211_node *ni, *obss;
 
+	IEEE80211_LOCK_ASSERT(ic);
+
 	ieee80211_node_table_reset(&ic->ic_sta, vap);
 	/* XXX multi-bss: wrong */
 	ieee80211_vap_reset_erp(vap);
@@ -854,7 +867,9 @@ ieee80211_sta_join1(struct ieee80211_node *selbs)
 	/*
 	 * Committed to selbs, setup state.
 	 */
+	IEEE80211_LOCK(ic);			/* XXX may recurse here, check callers. */
 	obss = vap->iv_update_bss(vap, selbs);	/* NB: caller assumed to bump refcnt */
+	IEEE80211_UNLOCK(ic);
 	/*
 	 * Check if old+new node have the same address in which
 	 * case we can reassociate when operating in sta mode.
diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c
index a3a2e6a5d027..c0f24344a982 100644
--- a/sys/net80211/ieee80211_proto.c
+++ b/sys/net80211/ieee80211_proto.c
@@ -826,6 +826,8 @@ vap_update_bss(struct ieee80211vap *vap, struct ieee80211_node *ni)
 {
 	struct ieee80211_node *obss;
 
+	IEEE80211_LOCK_ASSERT(vap->iv_ic);
+
 	obss = vap->iv_bss;
 	vap->iv_bss = ni;