⬢ DragonFlyBSD Kernel Audit
DF-3960 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/ath/ath_hal/ar5416/ar5416_reset.c	2026-09-17 05:19:20.556938969 +0000
+++ b/sys/dev/netif/ath/ath_hal/ar5416/ar5416_reset.c	2026-09-17 05:19:35.712746537 +0000
@@ -2369,7 +2369,18 @@
 
     /* Calculate the value of xpdgains from the xpdGain Mask */
     numXpdGain = ar5416GetXpdGainValues(ah, xpdMask, xpdGainValues);
-    
+
+    /*
+     * An empty xpdGain mask is invalid EEPROM data: with numXpdGain == 0
+     * the backfill loops in ar5416GetGainBoundariesAndPdadcs() read
+     * gainBoundaries[-1] and pdadcValues[-1]. Fail the calibration.
+     */
+    if (numXpdGain == 0) {
+        HALDEBUG(ah, HAL_DEBUG_ANY, "%s: invalid xpdGain mask 0x%x\n",
+            __func__, xpdMask);
+        return AH_FALSE;
+    }
+
     /* Write the detector gain biases and their number */
     ar5416WriteDetectorGainBiases(ah, numXpdGain, xpdGainValues);
 
@@ -2539,6 +2550,16 @@
         }
 
         sizeCurrVpdTable = (uint8_t)((maxPwrT4[i] - minPwrT4[i]) / 2 +1);
+        /*
+         * Degenerate pier ranges from corrupt EEPROM: a zero range makes
+         * the vpdStep read below index [-1]/[-2]; an inverted range wraps
+         * the uint8_t size past the 64-entry vpd table row, so the copy
+         * loop walks off the row. Clamp before deriving maxIndex.
+         */
+        if (sizeCurrVpdTable < 2)
+            sizeCurrVpdTable = 2;
+        if (sizeCurrVpdTable > AR5416_MAX_PWR_RANGE_IN_HALF_DB)
+            sizeCurrVpdTable = AR5416_MAX_PWR_RANGE_IN_HALF_DB;
         tgtIndex = (uint8_t)(pPdGainBoundaries[i] + tPdGainOverlap - (minPwrT4[i] / 2));
         maxIndex = (tgtIndex < sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;