Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 5 May 2025 14:59:10 GMT
From:      "Bjoern A. Zeeb" <bz@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: aff56b4f0b25 - main - net80211: fix a race between ieee80211_sta_join and scan entries
Message-ID:  <202505051459.545ExAeW021088@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by bz:

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

commit aff56b4f0b25c44c9c2cae9a3f816c4277057a71
Author:     Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-04-16 19:10:58 +0000
Commit:     Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-05-05 14:58:59 +0000

    net80211: fix a race between ieee80211_sta_join and scan entries
    
    We were seeing panics during ieee80211_sta_join() which seemed that
    the ni->ni_chan was not valid anymore, which was true.
    We also saw errors indicating data put into ni_ies became inalid.
    
    The problem was that the ieee80211_scan_entry passed into
    ieee80211_sta_join() (in the observed case from setmlme_assoc_sta())
    became invalid during ieee80211_alloc_node().
    As a result for the ni_chan case the the rateset and len in rates[1]
    became invalid.  Similarly for the IEs.
    
    Make a (deep)copy of the scan entry in setmlme_assoc_sta() and return
    the copy as once we leave ieee80211_scan_iterate() we can no longer
    rely on the scan entry to be valid.
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      3 days
    Reported by:    rm, ziaee, bz
    Tested by:      rm, ziaee, bz
    PR:             286063
    Reviewed by:    adrian (,emaste)
    Differential Revision: https://reviews.freebsd.org/D49865
---
 sys/net80211/ieee80211_ioctl.c | 26 +++++++++++++++++++++-----
 1 file changed, 21 insertions(+), 5 deletions(-)

diff --git a/sys/net80211/ieee80211_ioctl.c b/sys/net80211/ieee80211_ioctl.c
index caa0c77e2897..6c30325e5e32 100644
--- a/sys/net80211/ieee80211_ioctl.c
+++ b/sys/net80211/ieee80211_ioctl.c
@@ -1530,7 +1530,8 @@ struct scanlookup {
 	const uint8_t *mac;
 	int esslen;
 	const uint8_t *essid;
-	const struct ieee80211_scan_entry *se;
+	bool found;
+	struct ieee80211_scan_entry se;
 };
 
 /*
@@ -1540,6 +1541,10 @@ static void
 mlmelookup(void *arg, const struct ieee80211_scan_entry *se)
 {
 	struct scanlookup *look = arg;
+	int rv;
+
+	if (look->found)
+		return;
 
 	if (!IEEE80211_ADDR_EQ(look->mac, se->se_macaddr))
 		return;
@@ -1549,7 +1554,14 @@ mlmelookup(void *arg, const struct ieee80211_scan_entry *se)
 		if (memcmp(look->essid, se->se_ssid+2, look->esslen))
 			return;
 	}
-	look->se = se;
+	/*
+	 * First copy everything and then ensure we get our own copy of se_ies. */
+	look->se = *se;
+	look->se.se_ies.data = 0;
+	look->se.se_ies.len = 0;
+	rv = ieee80211_ies_init(&look->se.se_ies, se->se_ies.data, se->se_ies.len);
+	if (rv != 0)	/* No error */
+		look->found = true;
 }
 
 static int
@@ -1558,21 +1570,25 @@ setmlme_assoc_sta(struct ieee80211vap *vap,
 	const uint8_t ssid[IEEE80211_NWID_LEN])
 {
 	struct scanlookup lookup;
+	int rv;
 
 	KASSERT(vap->iv_opmode == IEEE80211_M_STA,
 	    ("expected opmode STA not %s",
 	    ieee80211_opmode_name[vap->iv_opmode]));
 
 	/* NB: this is racey if roaming is !manual */
-	lookup.se = NULL;
 	lookup.mac = mac;
 	lookup.esslen = ssid_len;
 	lookup.essid = ssid;
+	memset(&lookup.se, 0, sizeof(lookup.se));
+	lookup.found = false;
 	ieee80211_scan_iterate(vap, mlmelookup, &lookup);
-	if (lookup.se == NULL)
+	if (!lookup.found)
 		return ENOENT;
 	mlmedebug(vap, mac, IEEE80211_MLME_ASSOC, 0);
-	if (!ieee80211_sta_join(vap, lookup.se->se_chan, lookup.se))
+	rv = ieee80211_sta_join(vap, lookup.se.se_chan, &lookup.se);
+	ieee80211_ies_cleanup(&lookup.se.se_ies);
+	if (rv == 0)
 		return EIO;		/* XXX unique but could be better */
 	return 0;
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202505051459.545ExAeW021088>