⬢ DragonFlyBSD Kernel Audit
DF-2255 / fix.diff
← back to finding ↓ download raw
--- a/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
+++ b/sys/contrib/dev/ath/ath_hal/ar9300/ar9300_eeprom.c
@@ -3912,13 +3912,21 @@
             "%s: Found block at %x: "
             "code=%d ref=%d length=%d major=%d minor=%d\n",
             __func__, cptr, code, reference, length, major, minor);
-#ifdef DONTUSE
-        if (length >= 1024) {
+        /*
+         * DF-2255: length is an 11-bit field taken from the on-card
+         * eeprom (max 2047).  The whole block is read into
+         * u_int8_t word[MOUTPUT] below, so 4 + length + 2 bytes must
+         * fit in MOUTPUT or the read runs past the end of the stack
+         * buffer (1-5 byte kernel-stack overwrite with eeprom data).
+         * The old length >= 1024 guard was disabled behind
+         * "#ifdef DONTUSE"; enforce the real buffer bound instead.
+         */
+        if (length > MOUTPUT - compression_header_length -
+                compression_checksum_length) {
             HALDEBUG(ah, HAL_DEBUG_EEPROM, "%s: Skipping bad header\n", __func__);
             cptr -= compression_header_length;
             continue;
         }
-#endif
         osize = length;                
         (void) ar9300_calibration_data_read_array(
             ah, cptr, word,