⬢ DragonFlyBSD Kernel Audit
DF-3459 / fix.diff
← back to finding ↓ download raw
--- a/sys/netproto/802_11/wlan/ieee80211_rssadapt.c	2026-09-13 07:10:01.797256875 +0000
+++ b/sys/netproto/802_11/wlan/ieee80211_rssadapt.c	2026-09-13 07:10:25.728951317 +0000
@@ -194,6 +194,12 @@
 		}
 	} else
 		ra = ni->ni_rctls;
+	if (rs->rs_nrates == 0) {
+		/* An empty rateset leaves the pick loop below at rix -1,
+		 * which propagates into ra_rix and every threshold access. */
+		if_printf(vap->iv_ifp, "%s: empty rateset\n", __func__);
+		return;
+	}
 	ra->ra_rs = rsa;
 	ra->ra_rates = *rs;
 	rssadapt_updatestats(ra);
@@ -253,6 +259,9 @@
 	for (rix = rs->rs_nrates-1; rix >= 0; rix--)
 		if ((*thrs)[rix] < (rssi << 8))
 			break;
+	if (rix < 0)			/* no threshold strictly below rssi<<8:
+					 * rssi==0 (fresh node) or converged */
+		rix = 0;
 	if (rix != ra->ra_rix) {
 		/* update public rate */
 		ni->ni_txrate = ni->ni_rates.rs_rates[rix] & IEEE80211_RATE_VAL;
@@ -281,6 +290,11 @@
 	thrs = &ra->ra_rate_thresh[bucket(pktlen)];
 
 	rix = ra->ra_rix;
+	if ((int)rix < 0) {
+		/* rix is u_int: -1 becomes 0xffffffff and (*thrs)[rix]
+		 * would access ~+8GiB past the chunk. */
+		return;
+	}
 	last_thr = (*thrs)[rix];
 	(*thrs)[rix] = interpolate(master_expavgctl.rc_thresh,
 	    last_thr, (rssi << 8));