[PATCH iwlwifi-next 06/15] wifi: iwlwifi: fw: fix integer overflow in INI dump size calc
From: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Date: 2026-09-21 20:39:39
Subsystem:
intel wireless wifi link (iwlwifi), the rest · Maintainers:
Miri Korenblit, Linus Torvalds
From: Shahar Tzarfati <redacted> The INI debug dump get_size handlers compute the region size as hdr_size + ranges * (size + sizeof(range)) using u32 arithmetic. Both the per-range size and the number of ranges originate from debug TLVs with no upper bound, so the multiplication and additions can overflow u32. A small value passes the size < sizeof(*header) check in iwl_dump_ini_mem_prep(). Add the size computation in each handler using check_add_overflow()/check_mul_overflow() and return 0 when the result would overflow. For the block handler the variable per-pair sizes are summed with check_add_overflow() before computing size, since that accumulation can overflow on its own. Signed-off-by: Shahar Tzarfati <redacted> Assisted-by: GitHub-Copilot:claude-opus-4-8 Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> --- drivers/net/wireless/intel/iwlwifi/fw/dbg.c | 37 +++++++++++++++++---- 1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
index 6621ef9358bc..a314fabbf06d 100644
--- a/drivers/net/wireless/intel/iwlwifi/fw/dbg.c
+++ b/drivers/net/wireless/intel/iwlwifi/fw/dbg.c@@ -1016,8 +1016,16 @@ static u32 iwl_dump_ini_mem_get_size(struct iwl_fw_runtime *fwrt, if (!size || !ranges) return 0; - return sizeof(struct iwl_fw_ini_error_dump) + ranges * - (size + sizeof(struct iwl_fw_ini_error_dump_range)); + if (check_add_overflow(size, + (u32)sizeof(struct iwl_fw_ini_error_dump_range), + &size) || + check_mul_overflow(ranges, size, &size) || + check_add_overflow(size, + (u32)sizeof(struct iwl_fw_ini_error_dump), + &size)) + return 0; + + return size; } static u32
@@ -1028,15 +1036,24 @@ iwl_dump_ini_mem_block_get_size(struct iwl_fw_runtime *fwrt, struct iwl_fw_ini_addr_size *pairs = (void *)reg->addrs; u32 ranges = iwl_dump_ini_mem_block_ranges(fwrt, reg_data); u32 size = sizeof(struct iwl_fw_ini_error_dump); + u32 range_hdrs; int range; if (!ranges) return 0; for (range = 0; range < ranges; range++) - size += le32_to_cpu(pairs[range].size); + if (check_add_overflow(size, le32_to_cpu(pairs[range].size), + &size)) + return 0; + + if (check_mul_overflow(ranges, + (u32)sizeof(struct iwl_fw_ini_error_dump_range), + &range_hdrs) || + check_add_overflow(size, range_hdrs, &size)) + return 0; - return size + ranges * sizeof(struct iwl_fw_ini_error_dump_range); + return size; } static u32
@@ -1112,8 +1129,16 @@ static u32 iwl_dump_ini_mon_dbgi_get_size(struct iwl_fw_runtime *fwrt, if (!size || !ranges) return 0; - return sizeof(struct iwl_fw_ini_monitor_dump) + ranges * - (size + sizeof(struct iwl_fw_ini_error_dump_range)); + if (check_add_overflow(size, + (u32)sizeof(struct iwl_fw_ini_error_dump_range), + &size) || + check_mul_overflow(ranges, size, &size) || + check_add_overflow(size, + (u32)sizeof(struct iwl_fw_ini_monitor_dump), + &size)) + return 0; + + return size; } static u32 iwl_dump_ini_txf_get_size(struct iwl_fw_runtime *fwrt,
--
2.34.1