iwlwifi: d3: use struct_size() in kzalloc()
Subsystems (3)
PATCH 1/1 iwlwifi: d3: use struct_size() in kzalloc()
One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example:
struct foo {
int stuff;
void *entry[];
};instance = kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);
Instead of leaving these open-coded and prone to type mistakes, we can now use the new struct_size() helper:
instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL);
This issue was detected with the help of Coccinelle.
--- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +2 -4
@@ -1769,8 +1769,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, n_matches =0 ; } - net_detect =kzalloc (sizeof (*net_detect) + - (n_matches *sizeof (net_detect->matches[0 ])), + net_detect =kzalloc (struct_size (net_detect, matches, n_matches),GFP_KERNEL );if (!net_detect || !n_matches) goto out_report_nd;
@@ -1785,8 +1784,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,for (j =0 ; j <SCAN_OFFLOAD_MATCHING_CHANNELS_LEN ; j++) n_channels +=hweight8 (fw_match->matching_channels[j]); - match =kzalloc (sizeof (*match) + - (n_channels *sizeof (*match->channels)), + match =kzalloc (struct_size (match, channels, n_channels),GFP_KERNEL );if (!match) goto out_report_nd;
Signature · 1 line
2.7.4
Quoted 11 lines · Gustavo A. R. Silva
One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example:
struct foo { int stuff; void *entry[]; };instance =
kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);
Quoted 8 lines
Instead of leaving these open-coded and prone to type mistakes, we can now use the new
struct_size()helper:instance =
kzalloc(struct_size(instance, entry, count), GFP_KERNEL);This issue was detected with the help of Coccinelle.
Signed-off-by Gustavo A. R. Silva <[email protected]>
-Kees
Quoted 31 lines
--- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)drivers/net/wireless/intel/iwlwifi/mvm/d3.c +2
-5@@ -1769,8 +1769,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, n_matches =0 ; } - net_detect =kzalloc (sizeof (*net_detect) + - (n_matches *sizeof (net_detect->matches[0 ])), + net_detect =kzalloc (struct_size (net_detect, matches, n_matches),GFP_KERNEL );if (!net_detect || !n_matches) goto out_report_nd;@@ -1785,8 +1784,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,for (j =0 ; j <SCAN_OFFLOAD_MATCHING_CHANNELS_LEN ; j++) n_channels +=hweight8 (fw_match->matching_channels[j]); - match =kzalloc (sizeof (*match) + - (n_channels *sizeof (*match->channels)), + match =kzalloc (struct_size (match, channels, n_channels),GFP_KERNEL );if (!match) goto out_report_nd; --2.7.4
Signature · 2 lines
Kees Cook Pixel Security
Quoted 10 lines · Kees Cook
Quoted 8 lines · Gustavo A. R. Silva
One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example:
struct foo { int stuff; void *entry[]; };
Question for Gustavo.
Did you find any existing instances that are miscalculated?
I believe there are some cases like:
size = sizeof(struct foo) + count * sizeof(something); ptr = kmalloc(size); memset(ptr + sizeof(struct foo), 0, size - sizeof(struct foo));
where something could go wrong and not be detected.
Hi Joe,
Quoted 7 lines · Joe Perches
Quoted 6 lines · Kees Cook
Quoted 4 lines · Gustavo A. R. Silva
One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example:
Quoted 9 lines
Quoted 4 lines
Quoted 4 lines
struct foo { int stuff; void *entry[]; };Question for Gustavo.
Did you find any existing instances that are miscalculated?
I found the following bug:
https://lore.kernel.org/patchwork/patch/977357/
Quoted 8 lines
I believe there are some cases like:
size = sizeof(struct foo) + count * sizeof(something); ptr = kmalloc(size); memset(ptr + sizeof(struct foo), 0, size - sizeof(struct foo));where something could go wrong and not be detected.
It might be worth it to write a Coccinelle script for this.
--
Gustavo
Quoted 38 lines · Gustavo A. R. Silva
One of the more common cases of allocation size calculations is finding the size of a structure that has a zero-sized array at the end, along with memory for some number of elements for that array. For example:
struct foo { int stuff; void *entry[]; };instance =
kzalloc(sizeof(struct foo) + sizeof(void *) * count, GFP_KERNEL);Instead of leaving these open-coded and prone to type mistakes, we can now use the new
struct_size()helper:instance =
kzalloc(struct_size(instance, entry, count), GFP_KERNEL);This issue was detected with the help of Coccinelle.
Signed-off-by Gustavo A. R. Silva <[email protected]>--- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)drivers/net/wireless/intel/iwlwifi/mvm/d3.c +1
-2@@ -1769,8 +1769,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, n_matches =0 ; } - net_detect =kzalloc (sizeof (*net_detect) + - (n_matches *sizeof (net_detect->matches[0 ])), + net_detect =kzalloc (struct_size (net_detect, matches, n_matches),GFP_KERNEL );if (!net_detect || !n_matches) goto out_report_nd;
drivers/net/wireless/intel/iwlwifi/mvm/d3.c static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm, · line 1790
Quoted 9 lines
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +1
-2@@ -1785,8 +1784,7 @@ static void iwl_mvm_query_netdetect_reasons(struct iwl_mvm *mvm,for (j =0 ; j <SCAN_OFFLOAD_MATCHING_CHANNELS_LEN ; j++) n_channels +=hweight8 (fw_match->matching_channels[j]); - match =kzalloc (sizeof (*match) + - (n_channels *sizeof (*match->channels)), + match =kzalloc (struct_size (match, channels, n_channels),GFP_KERNEL );if (!match) goto out_report_nd;
Thanks! I applied this to our internal tree and it will reach the mainline following our normal process.
--
Cheers,
Luca.