vmalloc() and vzalloc() have 2-factor multiplication argument forms
vmalloc_array() and vcalloc() in <linux/vmalloc.h> that protect against
integer overflow during size calculation.
Commit 070580b0b174 ("checkpatch: Suggest kmalloc_obj family for sizeof
allocations") updated ALLOC_WITH_MULTIPLY for the (kv|k)[mz]alloc()
family to suggest kmalloc_objs(type, count, gfp), while vmalloc_array()
and vcalloc() retain the (count, size) signature.
Extend ALLOC_WITH_MULTIPLY to warn when vmalloc() or vzalloc() is called
with a 2-factor sizeof() multiplication and suggest vmalloc_array() or
vcalloc() respectively, including --fix support. Also include the 'v'
prefix in ALLOC_ARRAY_ARGS so swapped sizeof() first arguments to
vmalloc_array() and vcalloc() are flagged.
Link: https://github.com/KSPP/linux/issues/342
Signed-off-by: Iurii Trukhin <[email protected]>
---
scripts/checkpatch.pl | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index 8a7787d228a6..651a46f1fc40 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -7355,10 +7355,11 @@ sub process {
}
-# check for (kv|k)[mz]alloc with multiplies that could be
kmalloc_objs/kvmalloc_objs/kzalloc_objs/kvzalloc_objs
+# check for (kv|k|v)[mz]alloc with multiplies that could be
+# kmalloc_objs/kvmalloc_objs/kzalloc_objs/kvzalloc_objs/vmalloc_array/vcalloc
if ($perl_version_ok &&
defined $stat &&
- $stat =~
/^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/)
{
+ $stat =~
/^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*(?:,|\))/)
{
my $oldfunc = $3;
my $a1 = $4;
my $a2 = $10;
@@ -7366,6 +7367,8 @@ sub process {
$newfunc = "kvmalloc_objs" if ($oldfunc eq "kvmalloc");
$newfunc = "kvzalloc_objs" if ($oldfunc eq "kvzalloc");
$newfunc = "kzalloc_objs" if ($oldfunc eq "kzalloc");
+ $newfunc = "vmalloc_array" if ($oldfunc eq "vmalloc");
+ $newfunc = "vcalloc" if ($oldfunc eq "vzalloc");
my $r1 = $a1;
my $r2 = $a2;
if ($a1 =~ /^sizeof\s*\S/) {
@@ -7381,9 +7384,13 @@ sub process {
"Prefer $newfunc over $oldfunc with
multiply\n" . $herectx) &&
$cnt == 1 &&
$fix) {
- my $sized = trim($r2);
- $sized =~
s/^sizeof\s*\S\(?([^\)]*)\)?$/$1/;
- $fixed[$fixlinenr] =~
s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1
. ' = ' . "$newfunc(" . $sized . ', ' . trim($r1)/e;
+ if ($oldfunc =~ /^v/) {
+ $fixed[$fixlinenr] =~
s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(v[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1
. ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;
+ } else {
+ my $sized = trim($r2);
+ $sized =~
s/^sizeof\s*\S\(?([^\)]*)\)?$/$1/;
+ $fixed[$fixlinenr] =~
s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1
. ' = ' . "$newfunc(" . $sized . ', ' . trim($r1)/e;
+ }
}
}
}
@@ -7397,7 +7404,7 @@ sub process {
}
# check for alloc argument mismatch
- if ($line =~
/\b((?:devm_)?((?:k|kv)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/)
{
+ if ($line =~
/\b((?:devm_)?((?:k|kv|v)?(calloc|malloc_array)(?:_node)?))\s*\(\s*sizeof\b/)
{
WARN("ALLOC_ARRAY_ARGS",
"$1 uses number as first arg, sizeof is generally
wrong\n" .
$herecurr);
}
--
2.56.0