aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2021-12-10 11:12:41 +0200
committerLuca Coelho <luciano.coelho@intel.com>2021-12-21 12:35:05 +0200
commitccbffd690ec21b0891bf437ef5df9e5c63e0a980 (patch)
treeb0736e26a6f1d74c1b5d313a73765f941bc39ea7 /drivers/net/wireless
parentiwlwifi: mvm: fix 32-bit build in FTM (diff)
downloadlinux-dev-ccbffd690ec21b0891bf437ef5df9e5c63e0a980.tar.xz
linux-dev-ccbffd690ec21b0891bf437ef5df9e5c63e0a980.zip
iwlwifi: fix debug TLV parsing
Debug TLV parsing was missing size checks, so if a valid but too short TLV was encountered, it would attempt to read it. If the firmware file was arranged to be a multiple of pages long with this happening just before the end, it could crash reading out-of-bounds of a vmalloc area. Fix this by adding the relevant size check. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Luca Coelho <luciano.coelho@intel.com> Link: https://lore.kernel.org/r/iwlwifi.20211210110539.84848da8067f.Ifb4f80c95d283ec62e495a7928069af711b5fee2@changeid Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
index a8ebc26d1da1..c2fbda2ffe7e 100644
--- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
+++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c
@@ -300,14 +300,21 @@ static int (*dbg_tlv_alloc[])(struct iwl_trans *trans,
void iwl_dbg_tlv_alloc(struct iwl_trans *trans, const struct iwl_ucode_tlv *tlv,
bool ext)
{
- const struct iwl_fw_ini_header *hdr = (const void *)&tlv->data[0];
- u32 type = le32_to_cpu(tlv->type);
- u32 tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
- u32 domain = le32_to_cpu(hdr->domain);
enum iwl_ini_cfg_state *cfg_state = ext ?
&trans->dbg.external_ini_cfg : &trans->dbg.internal_ini_cfg;
+ const struct iwl_fw_ini_header *hdr = (const void *)&tlv->data[0];
+ u32 type;
+ u32 tlv_idx;
+ u32 domain;
int ret;
+ if (le32_to_cpu(tlv->length) < sizeof(*hdr))
+ return;
+
+ type = le32_to_cpu(tlv->type);
+ tlv_idx = type - IWL_UCODE_TLV_DEBUG_BASE;
+ domain = le32_to_cpu(hdr->domain);
+
if (domain != IWL_FW_INI_DOMAIN_ALWAYS_ON &&
!(domain & trans->dbg.domains_bitmap)) {
IWL_DEBUG_FW(trans,