Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2841a2d3 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach
Browse files

iwlwifi: check the size of the trigger struct from the firmware file



When we access the triggers we need to make sure that the
data we expect was actually provided by the firmware file.
Check this when we decode the triggers from the firmware
file.

Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 90cb1237
Loading
Loading
Loading
Loading
+28 −0
Original line number Original line Diff line number Diff line
@@ -1102,6 +1102,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
	const unsigned int api_max = drv->cfg->ucode_api_max;
	const unsigned int api_max = drv->cfg->ucode_api_max;
	unsigned int api_ok = drv->cfg->ucode_api_ok;
	unsigned int api_ok = drv->cfg->ucode_api_ok;
	const unsigned int api_min = drv->cfg->ucode_api_min;
	const unsigned int api_min = drv->cfg->ucode_api_min;
	size_t trigger_tlv_sz[FW_DBG_TRIGGER_MAX];
	u32 api_ver;
	u32 api_ver;
	int i;
	int i;
	bool load_module = false;
	bool load_module = false;
@@ -1221,8 +1222,35 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context)
		}
		}
	}
	}


	memset(&trigger_tlv_sz, 0xff, sizeof(trigger_tlv_sz));

	trigger_tlv_sz[FW_DBG_TRIGGER_MISSED_BEACONS] =
		sizeof(struct iwl_fw_dbg_trigger_missed_bcon);
	trigger_tlv_sz[FW_DBG_TRIGGER_CHANNEL_SWITCH] = 0;
	trigger_tlv_sz[FW_DBG_TRIGGER_FW_NOTIF] =
		sizeof(struct iwl_fw_dbg_trigger_cmd);
	trigger_tlv_sz[FW_DBG_TRIGGER_MLME] =
		sizeof(struct iwl_fw_dbg_trigger_mlme);
	trigger_tlv_sz[FW_DBG_TRIGGER_STATS] =
		sizeof(struct iwl_fw_dbg_trigger_stats);
	trigger_tlv_sz[FW_DBG_TRIGGER_RSSI] =
		sizeof(struct iwl_fw_dbg_trigger_low_rssi);
	trigger_tlv_sz[FW_DBG_TRIGGER_TXQ_TIMERS] =
		sizeof(struct iwl_fw_dbg_trigger_txq_timer);

	for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
	for (i = 0; i < ARRAY_SIZE(drv->fw.dbg_trigger_tlv); i++) {
		if (pieces->dbg_trigger_tlv[i]) {
		if (pieces->dbg_trigger_tlv[i]) {
			/*
			 * If the trigger isn't long enough, WARN and exit.
			 * Someone is trying to debug something and he won't
			 * be able to catch the bug he is trying to chase.
			 * We'd better be noisy to be sure he knows what's
			 * going on.
			 */
			if (WARN_ON(pieces->dbg_trigger_tlv_len[i] <
				    (trigger_tlv_sz[i] +
				     sizeof(struct iwl_fw_dbg_trigger_tlv))))
				goto out_free_fw;
			drv->fw.dbg_trigger_tlv_len[i] =
			drv->fw.dbg_trigger_tlv_len[i] =
				pieces->dbg_trigger_tlv_len[i];
				pieces->dbg_trigger_tlv_len[i];
			drv->fw.dbg_trigger_tlv[i] =
			drv->fw.dbg_trigger_tlv[i] =