@@ -566,6 +566,7 @@ sub hash_show_words {
566
566
$mode_perms_search .= ' |' if ($mode_perms_search ne " " );
567
567
$mode_perms_search .= $entry -> [0];
568
568
}
569
+ $mode_perms_search = " (?:${mode_perms_search} )" ;
569
570
570
571
our $mode_perms_world_writable = qr {
571
572
S_IWUGO |
@@ -600,6 +601,37 @@ sub hash_show_words {
600
601
$mode_perms_string_search .= ' |' if ($mode_perms_string_search ne " " );
601
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
636
our $allowed_asm_includes = qr { (?x:
605
637
irq|
@@ -6274,6 +6306,63 @@ sub process {
6274
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 =~ / \b DEVICE_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 /\b DEVICE_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 /\b DEVICE_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 /\b DEVICE_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
6366
# Mode permission misuses where it seems decimal should be octal
6278
6367
# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop
6279
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
6409
# check for uses of S_<PERMS> that could be octal for readability
6321
- if ($line =~ / \b $mode_perms_string_search \b / ) {
6322
- my $val = " " ;
6323
- my $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 );
6410
+ if ($line =~ / \b ($multi_mode_perms_string_search )\b / ) {
6411
+ my $oval = $1 ;
6412
+ my $octal = perms_to_octal($oval );
6341
6413
if (WARN(" SYMBOLIC_PERMS" ,
6342
6414
" Symbolic permissions '$oval ' are not preferred. Consider using octal permissions '$octal '.\n " . $herecurr ) &&
6343
6415
$fix ) {
6344
- $fixed [$fixlinenr ] =~ s /$val / $octal / ;
6416
+ $fixed [$fixlinenr ] =~ s /\Q $oval \E / $octal / ;
6345
6417
}
6346
6418
}
6347
6419
0 commit comments