Thread (16 messages) 16 messages, 1 author, 9d ago
COOLING9d

[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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help