⬢ DragonFlyBSD Kernel Audit
DF-3632 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/iwm/if_iwm.c	2026-09-15 10:51:39.216775004 +0000
+++ b/sys/dev/netif/iwm/if_iwm.c	2026-09-15 10:51:59.600513253 +0000
@@ -2332,6 +2332,38 @@
 	    sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data;
 	phy_sku = (const uint16_t *)sections[IWM_NVM_SECTION_TYPE_PHY_SKU].data;
 
+	/* Length requirements for every fixed-offset read below. */
+#define NVM_LEN_REQUIRED(idx)	(2 * (idx))	/* u16 index -> bytes */
+	if (sc->cfg->device_family == IWM_DEVICE_FAMILY_7000) {
+		if (sections[IWM_NVM_SECTION_TYPE_SW].length <
+		    NVM_LEN_REQUIRED(IWM_NVM_CHANNELS + IWM_NUM_CHANNELS) ||
+		    sections[sc->cfg->nvm_hw_section_num].length <
+		    NVM_LEN_REQUIRED(IWM_HW_ADDR + 3)) {
+			device_printf(sc->sc_dev,
+			    "NVM sections too short, refusing to parse\n");
+			return NULL;
+		}
+	} else {
+		uint16_t lar_offset = IWM_NVM_LAR_OFFSET_8000;
+		if (sections[IWM_NVM_SECTION_TYPE_SW].length <
+		    NVM_LEN_REQUIRED(IWM_N_HW_ADDRS_8000 + 2) ||
+		    sections[sc->cfg->nvm_type == IWM_NVM_SDP ?
+		    IWM_NVM_SECTION_TYPE_REGULATORY_SDP :
+		    IWM_NVM_SECTION_TYPE_REGULATORY].length <
+		    NVM_LEN_REQUIRED(imax(lar_offset,
+		    IWM_NVM_CHANNELS_8000 + IWM_NUM_CHANNELS_8000) + 1) ||
+		    sections[IWM_NVM_SECTION_TYPE_PHY_SKU].length <
+		    NVM_LEN_REQUIRED(IWM_SKU_8000 + 2)) {
+			device_printf(sc->sc_dev,
+			    "NVM sections too short, refusing to parse\n");
+			return NULL;
+		}
+		if (sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].data != NULL &&
+		    sections[IWM_NVM_SECTION_TYPE_MAC_OVERRIDE].length <
+		    NVM_LEN_REQUIRED(IWM_MAC_ADDRESS_OVERRIDE_8000 + 3))
+			mac_override = NULL;	/* fall back to HW regs */
+	}
+
 	return iwm_parse_nvm_data(sc, hw, sw, calib, mac_override,
 	    phy_sku, regulatory);
 }