iwlwifi: yoyo: don't access TLV before verifying len

If we access the TLV memory with shorter len than the struct
we access garbage data that was not given by the user.

On the way rewrite the checker in a cleaner way.

Signed-off-by: Mordechay Goodstein <mordechay.goodstein@intel.com>
Fixes: a9248de424 ("iwlwifi: dbg_ini: add TLV allocation new API support")
Signed-off-by: Luca Coelho <luciano.coelho@intel.com>
Link: https://lore.kernel.org/r/iwlwifi.20200424182644.54418c829390.I15d6b462a0e69a280b6c6cfbcb6bcb05bb5f79ee@changeid
This commit is contained in:
Mordechay Goodstein
2020-04-24 18:48:11 +03:00
committed by Luca Coelho
parent f25c418dca
commit 0c9e025e79
2 changed files with 24 additions and 25 deletions

View File

@@ -5,7 +5,7 @@
*
* GPL LICENSE SUMMARY
*
* Copyright (C) 2018 - 2019 Intel Corporation
* Copyright (C) 2018 - 2020 Intel Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
@@ -25,7 +25,7 @@
*
* BSD LICENSE
*
* Copyright (C) 2018 - 2019 Intel Corporation
* Copyright (C) 2018 - 2020 Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -304,6 +304,7 @@ enum iwl_fw_ini_buffer_location {
IWL_FW_INI_LOCATION_SRAM_PATH,
IWL_FW_INI_LOCATION_DRAM_PATH,
IWL_FW_INI_LOCATION_NPK_PATH,
IWL_FW_INI_LOCATION_NUM,
}; /* FW_DEBUG_TLV_BUFFER_LOCATION_E_VER_1 */
/**

View File

@@ -165,38 +165,36 @@ static int iwl_dbg_tlv_alloc_buf_alloc(struct iwl_trans *trans,
struct iwl_ucode_tlv *tlv)
{
struct iwl_fw_ini_allocation_tlv *alloc = (void *)tlv->data;
u32 buf_location = le32_to_cpu(alloc->buf_location);
u32 alloc_id = le32_to_cpu(alloc->alloc_id);
u32 buf_location;
u32 alloc_id;
if (le32_to_cpu(tlv->length) != sizeof(*alloc) ||
(buf_location != IWL_FW_INI_LOCATION_SRAM_PATH &&
buf_location != IWL_FW_INI_LOCATION_DRAM_PATH &&
buf_location != IWL_FW_INI_LOCATION_NPK_PATH)) {
IWL_ERR(trans,
"WRT: Invalid allocation TLV\n");
if (le32_to_cpu(tlv->length) != sizeof(*alloc))
return -EINVAL;
}
buf_location = le32_to_cpu(alloc->buf_location);
alloc_id = le32_to_cpu(alloc->alloc_id);
if (buf_location == IWL_FW_INI_LOCATION_INVALID ||
buf_location >= IWL_FW_INI_LOCATION_NUM)
goto err;
if (alloc_id == IWL_FW_INI_ALLOCATION_INVALID ||
alloc_id >= IWL_FW_INI_ALLOCATION_NUM)
goto err;
if ((buf_location == IWL_FW_INI_LOCATION_SRAM_PATH ||
buf_location == IWL_FW_INI_LOCATION_NPK_PATH) &&
alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1) {
IWL_ERR(trans,
"WRT: Allocation TLV for SMEM/NPK path must have id %u (current: %u)\n",
IWL_FW_INI_ALLOCATION_ID_DBGC1, alloc_id);
return -EINVAL;
}
if (alloc_id == IWL_FW_INI_ALLOCATION_INVALID ||
alloc_id >= IWL_FW_INI_ALLOCATION_NUM) {
IWL_ERR(trans,
"WRT: Invalid allocation id %u for allocation TLV\n",
alloc_id);
return -EINVAL;
}
alloc_id != IWL_FW_INI_ALLOCATION_ID_DBGC1)
goto err;
trans->dbg.fw_mon_cfg[alloc_id] = *alloc;
return 0;
err:
IWL_ERR(trans,
"WRT: Invalid allocation id %u and/or location id %u for allocation TLV\n",
alloc_id, buf_location);
return -EINVAL;
}
static int iwl_dbg_tlv_alloc_hcmd(struct iwl_trans *trans,