Skip to content

Commit 0b52376

Browse files
JoePerchestorvalds
authored andcommitted
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>
1 parent cd8618a commit 0b52376

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

lib/vsprintf.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1477,6 +1477,9 @@ int kptr_restrict __read_mostly;
14771477
* by an extra set of alphanumeric characters that are extended format
14781478
* specifiers.
14791479
*
1480+
* Please update scripts/checkpatch.pl when adding/removing conversion
1481+
* characters. (Search for "check for vsprintf extension").
1482+
*
14801483
* Right now we handle:
14811484
*
14821485
* - 'F' For symbolic function descriptor pointers with offset

scripts/checkpatch.pl

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5663,6 +5663,32 @@ sub process {
56635663
}
56645664
}
56655665

5666+
# check for vsprintf extension %p<foo> misuses
5667+
if ($^V && $^V ge 5.10.0 &&
5668+
defined $stat &&
5669+
$stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&
5670+
$1 !~ /^_*volatile_*$/) {
5671+
my $bad_extension = "";
5672+
my $lc = $stat =~ tr@\n@@;
5673+
$lc = $lc + $linenr;
5674+
for (my $count = $linenr; $count <= $lc; $count++) {
5675+
my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));
5676+
$fmt =~ s/%%//g;
5677+
if ($fmt =~ /(\%[\*\d\.]*p(?![\WFfSsBKRraEhMmIiUDdgVCbGN]).)/) {
5678+
$bad_extension = $1;
5679+
last;
5680+
}
5681+
}
5682+
if ($bad_extension ne "") {
5683+
my $stat_real = raw_line($linenr, 0);
5684+
for (my $count = $linenr + 1; $count <= $lc; $count++) {
5685+
$stat_real = $stat_real . "\n" . raw_line($count, 0);
5686+
}
5687+
WARN("VSPRINTF_POINTER_EXTENSION",
5688+
"Invalid vsprintf pointer extension '$bad_extension'\n" . "$here\n$stat_real\n");
5689+
}
5690+
}
5691+
56665692
# Check for misused memsets
56675693
if ($^V && $^V ge 5.10.0 &&
56685694
defined $stat &&

0 commit comments

Comments
 (0)