checkpatch: add ability to find bad uses of vsprintf %p<foo> extensions

%pK was at least once misused at %pk in an out-of-tree module.  This
lead to some security concerns.  Add the ability to track single and
multiple line statements for misuses of %p<foo>.

[akpm@linux-foundation.org: add helpful comment into lib/vsprintf.c]
[akpm@linux-foundation.org: text tweak]
Link: http://lkml.kernel.org/r/163a690510e636a23187c0dc9caa09ddac6d4cde.1488228427.git.joe@perches.com
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: Kees Cook <keescook@chromium.org>
Acked-by: William Roberts <william.c.roberts@intel.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Joe Perches 2017-05-08 15:55:36 -07:00 committed by Linus Torvalds
parent cd8618ab3d
commit 0b523769eb
2 changed files with 29 additions and 0 deletions

View File

@ -1477,6 +1477,9 @@ int kptr_restrict __read_mostly;
* by an extra set of alphanumeric characters that are extended format * by an extra set of alphanumeric characters that are extended format
* specifiers. * specifiers.
* *
* Please update scripts/checkpatch.pl when adding/removing conversion
* characters. (Search for "check for vsprintf extension").
*
* Right now we handle: * Right now we handle:
* *
* - 'F' For symbolic function descriptor pointers with offset * - 'F' For symbolic function descriptor pointers with offset

View File

@ -5663,6 +5663,32 @@ sub process {
} }
} }
# check for vsprintf extension %p<foo> misuses
if ($^V && $^V ge 5.10.0 &&
defined $stat &&
$stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
$1 !~ /^_*volatile_*$/) {
my $bad_extension = "";
my $lc = $stat =~ tr@\n@@;
$lc = $lc + $linenr;
for (my $count = $linenr; $count <= $lc; $count++) {
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
$fmt =~ s/%%//g;
if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) {
$bad_extension = $1;
last;
}
}
if ($bad_extension ne "") {
my $stat_real = raw_line($linenr, 0);
for (my $count = $linenr + 1; $count <= $lc; $count++) {
$stat_real = $stat_real . "\n" . raw_line($count, 0);
}
WARN("VSPRINTF_POINTER_EXTENSION",
"Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
}
}
# Check for misused memsets # Check for misused memsets
if ($^V && $^V ge 5.10.0 && if ($^V && $^V ge 5.10.0 &&
defined $stat && defined $stat &&