Skip to contentSkip to conversation

wifi: iwlwifi: mld: Start the netdetect match counts at zero

PATCH New Kees Cook 1 participant 1 message Nov 13

Subsystems (2)
lore
Share & tools
lore

Kees Cook

author
#0 lore raw

PATCH 1/1 wifi: iwlwifi: mld: Start the netdetect match counts at zero

iwl_mld_process_netdetect_res() allocates the netdetect results with kzalloc_flex(), and iwl_mld_set_netdetect_info() allocates each match the same way. kzalloc_flex() sets the __counted_by() counters "n_matches" and "n_channels" to the allocated sizes when the compiler supports __builtin_counted_by_ref(), but iwl_mld_set_netdetect_info() uses them as the number of entries filled so far, expecting them to start at zero as they did when the results came from kzalloc(). Starting from the allocated sizes, every match and channel is stored past the end of its array.

Reset both counters after allocation, since they are "usage" counters, not "total allocation" counters. Also increment each counter before storing the entry it counts, so that no store is beyond the __counted_by() bound at the time it is made.

Build tested ARCH=x86_64 defconfig with CONFIG_IWLMLD=m and W=1, with GCC 16.2.0.

Fixes 69050f8d6d075 ("treewide: Replace kmalloc with kmalloc_obj for non-scalar types")
---
 drivers/net/wireless/intel/iwlwifi/mld/d3.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
drivers/net/wireless/intel/iwlwifi/mld/d3.c +9 -4
index ce959363f62c..711877ac4c23 100644
@@ -1437,9 +1437,11 @@ iwl_mld_set_netdetect_info(struct iwl_mld *mld,
 		match = kzalloc_flex(*match, channels, n_channels);
 		if (!match)
 			return;
+		/* The channels are counted below as they are added. */
+		match->n_channels = 0;
 
-		netdetect_info->matches[netdetect_info->n_matches] = match;
 		netdetect_info->n_matches++;
+		netdetect_info->matches[netdetect_info->n_matches - 1] = match;
 
 		/* We inverted the order of the SSIDs in the scan
 		 * request, so invert the index here.
@@ -1457,9 +1459,9 @@ iwl_mld_set_netdetect_info(struct iwl_mld *mld,
 		for_each_set_bit(j,
 				 (unsigned long *)&matches[i].matching_channels[0],
 				 sizeof(matches[i].matching_channels)) {
-			match->channels[match->n_channels] =
-				netdetect_cfg->channels[j]->center_freq;
 			match->n_channels++;
+			match->channels[match->n_channels - 1] =
+				netdetect_cfg->channels[j]->center_freq;
 		}
 	}
 }
@@ -1512,10 +1514,13 @@ iwl_mld_process_netdetect_res(struct iwl_mld *mld,
 	}
 	n_matches = hweight_long(matched_profiles);
 	netdetect_info = kzalloc_flex(*netdetect_info, matches, n_matches);
-	if (netdetect_info)
+	if (netdetect_info) {
+		/* iwl_mld_set_netdetect_info() counts the matches it adds. */
+		netdetect_info->n_matches = 0;
 		iwl_mld_set_netdetect_info(mld, netdetect_cfg, netdetect_info,
 					   resume_data->netdetect_res,
 					   matched_profiles);
+	}
 
 	wakeup.net_detect = netdetect_info;
  out:
Signature · 1 line
2.55.0