⬢ DragonFlyBSD Kernel Audit
DF-4816 / fix.diff
← back to finding ↓ download raw
--- a/sys/dev/netif/iwm/if_iwm_phy_db.c
+++ b/sys/dev/netif/iwm/if_iwm_phy_db.c
@@ -146,6 +146,11 @@
 
 #define CHANNEL_NUM_SIZE	4	/* num of channels in calib_ch size */
 
+/*
+ * Sanity cap on firmware-supplied channel-group ids (groups per type).
+ */
+#define IWM_PHY_DB_MAX_CH_GROUPS	255
+
 struct iwm_phy_db_entry {
 	uint16_t	size;
 	uint8_t		*data;
@@ -277,6 +282,12 @@
 
 	if (type == IWM_PHY_DB_CALIB_CHG_PAPD) {
 		chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
+		if (chg_id >= IWM_PHY_DB_MAX_CH_GROUPS) {
+			device_printf(phy_db->sc->sc_dev,
+			    "%s: invalid PAPD channel group id %d\n",
+			    __func__, chg_id);
+			return EINVAL;
+		}
 		if (phy_db && !phy_db->calib_ch_group_papd) {
 			/*
 			 * Firmware sends the largest index first, so we can use
@@ -291,6 +302,12 @@
 		}
 	} else if (type == IWM_PHY_DB_CALIB_CHG_TXP) {
 		chg_id = le16toh(*(uint16_t *)phy_db_notif->data);
+		if (chg_id >= IWM_PHY_DB_MAX_CH_GROUPS) {
+			device_printf(phy_db->sc->sc_dev,
+			    "%s: invalid TXP channel group id %d\n",
+			    __func__, chg_id);
+			return EINVAL;
+		}
 		if (phy_db && !phy_db->calib_ch_group_txp) {
 			/*
 			 * Firmware sends the largest index first, so we can use
@@ -455,7 +472,7 @@
 static int
 iwm_phy_db_send_all_channel_groups(struct iwm_phy_db *phy_db,
 				   enum iwm_phy_db_section_type type,
-				   uint8_t max_ch_groups)
+				   int max_ch_groups)
 {
 	uint16_t i;
 	int err;
@@ -538,23 +555,27 @@
 	}
 
 	/* Send all the TXP channel specific data */
-	err = iwm_phy_db_send_all_channel_groups(phy_db,
-	    IWM_PHY_DB_CALIB_CHG_PAPD, phy_db->n_group_papd);
-	if (err) {
-		device_printf(phy_db->sc->sc_dev,
-		    "%s: Cannot send channel specific PAPD groups, %d\n",
-		    __func__, err);
-		return err;
+	if (phy_db->n_group_papd > 0) {
+		err = iwm_phy_db_send_all_channel_groups(phy_db,
+		    IWM_PHY_DB_CALIB_CHG_PAPD, phy_db->n_group_papd);
+		if (err) {
+			device_printf(phy_db->sc->sc_dev,
+			    "%s: Cannot send channel specific PAPD groups, %d\n",
+			    __func__, err);
+			return err;
+		}
 	}
 
 	/* Send all the TXP channel specific data */
-	err = iwm_phy_db_send_all_channel_groups(phy_db,
-	    IWM_PHY_DB_CALIB_CHG_TXP, phy_db->n_group_txp);
-	if (err) {
-		device_printf(phy_db->sc->sc_dev,
-		    "%s: Cannot send channel specific TX power groups, "
-		    "%d\n", __func__, err);
-		return err;
+	if (phy_db->n_group_txp > 0) {
+		err = iwm_phy_db_send_all_channel_groups(phy_db,
+		    IWM_PHY_DB_CALIB_CHG_TXP, phy_db->n_group_txp);
+		if (err) {
+			device_printf(phy_db->sc->sc_dev,
+			    "%s: Cannot send channel specific TX power groups, "
+			    "%d\n", __func__, err);
+			return err;
+		}
 	}
 
 	IWM_DPRINTF(phy_db->sc, IWM_DEBUG_CMD | IWM_DEBUG_RESET,