diff options
| author | Joe Perches <joe@perches.com> | 2018-02-06 18:38:55 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-02-06 21:32:45 -0500 |
| commit | 001804689b0d41410ae483d3e3dcdb16c3a6640f (patch) | |
| tree | 322c581d2e28210142d6604bf67f01203aa05608 /scripts | |
| parent | 3f7f335dbc8675e0b55b2cedb5164b7ead1e4fe6 (diff) | |
checkpatch: add a few DEVICE_ATTR style tests
DEVICE_ATTR is a declaration macro that has a few alternate and
preferred forms like DEVICE_ATTR_RW, DEVICE_ATTR_RO, and DEVICE_ATTR.
As well, many uses of DEVICE_ATTR could use the preferred forms when the
show or store functions are also named in a regular form.
Suggest the preferred forms when appropriate.
Also emit a permissions warning if the the permissions are not the
typical 0644, 0444, or 0200.
Link: http://lkml.kernel.org/r/725864f363d91d1e1e6894a39fb57662eabd6d65.1513803306.git.joe@perches.com
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/checkpatch.pl | 114 |
1 files changed, 93 insertions, 21 deletions
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7c635146cb80..51905634be23 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
| @@ -566,6 +566,7 @@ foreach my $entry (@mode_permission_funcs) { | |||
| 566 | $mode_perms_search .= '|' if ($mode_perms_search ne ""); | 566 | $mode_perms_search .= '|' if ($mode_perms_search ne ""); |
| 567 | $mode_perms_search .= $entry->[0]; | 567 | $mode_perms_search .= $entry->[0]; |
| 568 | } | 568 | } |
| 569 | $mode_perms_search = "(?:${mode_perms_search})"; | ||
| 569 | 570 | ||
| 570 | our $mode_perms_world_writable = qr{ | 571 | our $mode_perms_world_writable = qr{ |
| 571 | S_IWUGO | | 572 | S_IWUGO | |
| @@ -600,6 +601,37 @@ foreach my $entry (keys %mode_permission_string_types) { | |||
| 600 | $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); | 601 | $mode_perms_string_search .= '|' if ($mode_perms_string_search ne ""); |
| 601 | $mode_perms_string_search .= $entry; | 602 | $mode_perms_string_search .= $entry; |
| 602 | } | 603 | } |
| 604 | our $single_mode_perms_string_search = "(?:${mode_perms_string_search})"; | ||
| 605 | our $multi_mode_perms_string_search = qr{ | ||
| 606 | ${single_mode_perms_string_search} | ||
| 607 | (?:\s*\|\s*${single_mode_perms_string_search})* | ||
| 608 | }x; | ||
| 609 | |||
| 610 | sub perms_to_octal { | ||
| 611 | my ($string) = @_; | ||
| 612 | |||
| 613 | return trim($string) if ($string =~ /^\s*0[0-7]{3,3}\s*$/); | ||
| 614 | |||
| 615 | my $val = ""; | ||
| 616 | my $oval = ""; | ||
| 617 | my $to = 0; | ||
| 618 | my $curpos = 0; | ||
| 619 | my $lastpos = 0; | ||
| 620 | while ($string =~ /\b(($single_mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { | ||
| 621 | $curpos = pos($string); | ||
| 622 | my $match = $2; | ||
| 623 | my $omatch = $1; | ||
| 624 | last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); | ||
| 625 | $lastpos = $curpos; | ||
| 626 | $to |= $mode_permission_string_types{$match}; | ||
| 627 | $val .= '\s*\|\s*' if ($val ne ""); | ||
| 628 | $val .= $match; | ||
| 629 | $oval .= $omatch; | ||
| 630 | } | ||
| 631 | $oval =~ s/^\s*\|\s*//; | ||
| 632 | $oval =~ s/\s*\|\s*$//; | ||
| 633 | return sprintf("%04o", $to); | ||
| 634 | } | ||
| 603 | 635 | ||
| 604 | our $allowed_asm_includes = qr{(?x: | 636 | our $allowed_asm_includes = qr{(?x: |
| 605 | irq| | 637 | irq| |
| @@ -6274,6 +6306,63 @@ sub process { | |||
| 6274 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); | 6306 | "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr); |
| 6275 | } | 6307 | } |
| 6276 | 6308 | ||
| 6309 | # check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO> | ||
| 6310 | # and whether or not function naming is typical and if | ||
| 6311 | # DEVICE_ATTR permissions uses are unusual too | ||
| 6312 | if ($^V && $^V ge 5.10.0 && | ||
| 6313 | defined $stat && | ||
| 6314 | $stat =~ /\bDEVICE_ATTR\s*\(\s*(\w+)\s*,\s*\(?\s*(\s*(?:${multi_mode_perms_string_search}|0[0-7]{3,3})\s*)\s*\)?\s*,\s*(\w+)\s*,\s*(\w+)\s*\)/) { | ||
| 6315 | my $var = $1; | ||
| 6316 | my $perms = $2; | ||
| 6317 | my $show = $3; | ||
| 6318 | my $store = $4; | ||
| 6319 | my $octal_perms = perms_to_octal($perms); | ||
| 6320 | if ($show =~ /^${var}_show$/ && | ||
| 6321 | $store =~ /^${var}_store$/ && | ||
| 6322 | $octal_perms eq "0644") { | ||
| 6323 | if (WARN("DEVICE_ATTR_RW", | ||
| 6324 | "Use DEVICE_ATTR_RW\n" . $herecurr) && | ||
| 6325 | $fix) { | ||
| 6326 | $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/; | ||
| 6327 | } | ||
| 6328 | } elsif ($show =~ /^${var}_show$/ && | ||
| 6329 | $store =~ /^NULL$/ && | ||
| 6330 | $octal_perms eq "0444") { | ||
| 6331 | if (WARN("DEVICE_ATTR_RO", | ||
| 6332 | "Use DEVICE_ATTR_RO\n" . $herecurr) && | ||
| 6333 | $fix) { | ||
| 6334 | $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/; | ||
| 6335 | } | ||
| 6336 | } elsif ($show =~ /^NULL$/ && | ||
| 6337 | $store =~ /^${var}_store$/ && | ||
| 6338 | $octal_perms eq "0200") { | ||
| 6339 | if (WARN("DEVICE_ATTR_WO", | ||
| 6340 | "Use DEVICE_ATTR_WO\n" . $herecurr) && | ||
| 6341 | $fix) { | ||
| 6342 | $fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/; | ||
| 6343 | } | ||
| 6344 | } elsif ($octal_perms eq "0644" || | ||
| 6345 | $octal_perms eq "0444" || | ||
| 6346 | $octal_perms eq "0200") { | ||
| 6347 | my $newshow = "$show"; | ||
| 6348 | $newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show"); | ||
| 6349 | my $newstore = $store; | ||
| 6350 | $newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store"); | ||
| 6351 | my $rename = ""; | ||
| 6352 | if ($show ne $newshow) { | ||
| 6353 | $rename .= " '$show' to '$newshow'"; | ||
| 6354 | } | ||
| 6355 | if ($store ne $newstore) { | ||
| 6356 | $rename .= " '$store' to '$newstore'"; | ||
| 6357 | } | ||
| 6358 | WARN("DEVICE_ATTR_FUNCTIONS", | ||
| 6359 | "Consider renaming function(s)$rename\n" . $herecurr); | ||
| 6360 | } else { | ||
| 6361 | WARN("DEVICE_ATTR_PERMS", | ||
| 6362 | "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr); | ||
| 6363 | } | ||
| 6364 | } | ||
| 6365 | |||
| 6277 | # Mode permission misuses where it seems decimal should be octal | 6366 | # Mode permission misuses where it seems decimal should be octal |
| 6278 | # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop | 6367 | # This uses a shortcut match to avoid unnecessary uses of a slow foreach loop |
| 6279 | # o Ignore module_param*(...) uses with a decimal 0 permission as that has a | 6368 | # o Ignore module_param*(...) uses with a decimal 0 permission as that has a |
| @@ -6318,30 +6407,13 @@ sub process { | |||
| 6318 | } | 6407 | } |
| 6319 | 6408 | ||
| 6320 | # check for uses of S_<PERMS> that could be octal for readability | 6409 | # check for uses of S_<PERMS> that could be octal for readability |
| 6321 | if ($line =~ /\b$mode_perms_string_search\b/) { | 6410 | if ($line =~ /\b($multi_mode_perms_string_search)\b/) { |
| 6322 | my $val = ""; | 6411 | my $oval = $1; |
| 6323 | my $oval = ""; | 6412 | my $octal = perms_to_octal($oval); |
| 6324 | my $to = 0; | ||
| 6325 | my $curpos = 0; | ||
| 6326 | my $lastpos = 0; | ||
| 6327 | while ($line =~ /\b(($mode_perms_string_search)\b(?:\s*\|\s*)?\s*)/g) { | ||
| 6328 | $curpos = pos($line); | ||
| 6329 | my $match = $2; | ||
| 6330 | my $omatch = $1; | ||
| 6331 | last if ($lastpos > 0 && ($curpos - length($omatch) != $lastpos)); | ||
| 6332 | $lastpos = $curpos; | ||
| 6333 | $to |= $mode_permission_string_types{$match}; | ||
| 6334 | $val .= '\s*\|\s*' if ($val ne ""); | ||
| 6335 | $val .= $match; | ||
| 6336 | $oval .= $omatch; | ||
| 6337 | } | ||
| 6338 | $oval =~ s/^\s*\|\s*//; | ||
| 6339 | $oval =~ s/\s*\|\s*$//; | ||
| 6340 | my $octal = sprintf("%04o", $to); | ||
| 6341 | if (WARN("SYMBOLIC_PERMS", | 6413 | if (WARN("SYMBOLIC_PERMS", |
| 6342 | "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && | 6414 | "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) && |
| 6343 | $fix) { | 6415 | $fix) { |
| 6344 | $fixed[$fixlinenr] =~ s/$val/$octal/; | 6416 | $fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/; |
| 6345 | } | 6417 | } |
| 6346 | } | 6418 | } |
| 6347 | 6419 | ||
