⬢ DragonFlyBSD Kernel Audit
DF-4850 / fix.diff
← back to finding ↓ download raw
# DF-4850 fix — store per-series rate-table indices in amrr_node and return
# them from ath_rate_getxtxrates(), honoring the ath_rc_series.rix contract
# ("ratetable index, not rate code", if_athrate.h:91).
#
# NOTE: this fixes the index/code confusion only. The unchecked sc_rixmap 0xff
# sentinel (DF-1931) needs its own bounds check; without it the rix1/rix2 values
# stored here can still be 0xff. Apply both.
#
# Authored post-verification against the read-only sys/ tree; never applied.

diff --git a/sys/dev/netif/ath/ath_rate/amrr/amrr.h b/sys/dev/netif/ath/ath_rate/amrr/amrr.h
index 1111111..2222222 100644
--- a/sys/dev/netif/ath/ath_rate/amrr/amrr.h
+++ b/sys/dev/netif/ath/ath_rate/amrr/amrr.h
@@ -64,6 +64,9 @@ struct amrr_node {
 	/* rate index et al. */
 	u_int8_t	amn_tx_rix0;	/* series 0 rate index */
 	u_int8_t	amn_tx_rix1;	/* series 1 rate index */
 	u_int8_t	amn_tx_rix2;	/* series 2 rate index */
 	u_int8_t	amn_tx_rix3;	/* series 3 rate index */
 	u_int8_t	amn_tx_rate0;	/* series 0 h/w rate */
 	u_int8_t	amn_tx_rate1;	/* series 1 h/w rate */
 	u_int8_t	amn_tx_rate2;	/* series 2 h/w rate */
diff --git a/sys/dev/netif/ath/ath_rate/amrr/amrr.c b/sys/dev/netif/ath/ath_rate/amrr/amrr.c
index 1111111..3333333 100644
--- a/sys/dev/netif/ath/ath_rate/amrr/amrr.c
+++ b/sys/dev/netif/ath/ath_rate/amrr/amrr.c
@@ -132,10 +132,10 @@ ath_rate_getxtxrates(struct ath_softc *sc, struct ath_node *an,
 	struct amrr_node *amn = ATH_NODE_AMRR(an);
 
 	rc[0].flags = rc[1].flags = rc[2].flags = rc[3].flags = 0;
 
-	rc[0].rix = amn->amn_tx_rate0;
-	rc[1].rix = amn->amn_tx_rate1;
-	rc[2].rix = amn->amn_tx_rate2;
-	rc[3].rix = amn->amn_tx_rate3;
+	rc[0].rix = amn->amn_tx_rix0;
+	rc[1].rix = amn->amn_tx_rix1;
+	rc[2].rix = amn->amn_tx_rix2;
+	rc[3].rix = amn->amn_tx_rix3;
 
 	rc[0].tries = amn->amn_tx_try0;
 	rc[1].tries = amn->amn_tx_try1;
@@ -253,26 +253,32 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
 			amn->amn_tx_try0 = 1;
 			amn->amn_tx_try1 = 1;
 			amn->amn_tx_try2 = 1;
 			amn->amn_tx_try3 = 1;
 			if (--rate >= 0) {
 				rix = sc->sc_rixmap[
 						    ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
+				amn->amn_tx_rix1 = rix;
 				amn->amn_tx_rate1 = rt->info[rix].rateCode;
 				amn->amn_tx_rate1sp = amn->amn_tx_rate1 |
 					rt->info[rix].shortPreamble;
 			} else {
+				amn->amn_tx_rix1 = 0;
 				amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0;
 			}
 			if (--rate >= 0) {
 				rix = sc->sc_rixmap[
 						    ni->ni_rates.rs_rates[rate]&IEEE80211_RATE_VAL];
+				amn->amn_tx_rix2 = rix;
 				amn->amn_tx_rate2 = rt->info[rix].rateCode;
 				amn->amn_tx_rate2sp = amn->amn_tx_rate2 |
 					rt->info[rix].shortPreamble;
 			} else {
+				amn->amn_tx_rix2 = 0;
 				amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0;
 			}
 			if (rate > 0) {
 				/* NB: only do this if we didn't already do it above */
+				amn->amn_tx_rix3 = 0;
 				amn->amn_tx_rate3 = rt->info[0].rateCode;
 				amn->amn_tx_rate3sp =
 					amn->amn_tx_rate3 | rt->info[0].shortPreamble;
 			} else {
+				amn->amn_tx_rix3 = 0;
 				amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0;
 			}
 		} else {
@@ -286,6 +292,10 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate)
 			amn->amn_tx_try1 = 0;
 			amn->amn_tx_try2 = 0;
 			amn->amn_tx_try3 = 0;
+			amn->amn_tx_rix1 = 0;
+			amn->amn_tx_rix2 = 0;
+			amn->amn_tx_rix3 = 0;
 			amn->amn_tx_rate1 = amn->amn_tx_rate1sp = 0;
 			amn->amn_tx_rate2 = amn->amn_tx_rate2sp = 0;
 			amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0;