lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 23 Oct 2020 15:13:07 +0530 From: Dwaipayan Ray <dwaipayanray1@...il.com> To: joe@...ches.com Cc: linux-kernel-mentees@...ts.linuxfoundation.org, dwaipayanray1@...il.com, linux-kernel@...r.kernel.org, lukas.bulwahn@...il.com Subject: [PATCH RFC v2] checkpatch: extend attributes check to handle more patterns It is generally preferred that the macros from include/linux/compiler_attributes.h are used, unless there is a reason not to. Checkpatch currently checks __attribute__ for each of packed, aligned, printf, scanf, and weak. Other declarations in compiler_attributes.h are not handled. Add a generic test to check the presence of such attributes. Some attributes require more specific handling and are kept separate. New attributes which are now handled are: __alias__(#symbol) __always_inline__ __assume_aligned__(a, ## __VA_ARGS__) __cold__ __const__ __copy__(symbol) __designated_init__ __externally_visible__ __gnu_inline__ __malloc__ __mode__(x) __no_caller_saved_registers__ __noclone__ __fallthrough__ __noinline__ __nonstring__ __noreturn__ __pure__ __unused__ __used__ Link: https://lore.kernel.org/linux-kernel-mentees/3ec15b41754b01666d94b76ce51b9832c2dd577a.camel@perches.com/ Suggested-by: Joe Perches <joe@...ches.com> Signed-off-by: Dwaipayan Ray <dwaipayanray1@...il.com> --- scripts/checkpatch.pl | 130 ++++++++++++++++++++++++++++++------------ 1 file changed, 94 insertions(+), 36 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 7e505688257a..69324c2e55d6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6155,50 +6155,108 @@ sub process { } } -# Check for __attribute__ packed, prefer __packed +# Check for compiler attributes if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) { - WARN("PREFER_PACKED", - "__packed is preferred over __attribute__((packed))\n" . $herecurr); - } + $line =~ /\b__attribute__\s*\(\s*\((.*)\)\s*\)/) { + my $attr = trim($1); + + my $attr_list = qr { + __alias__| + __aligned__$| + __aligned__\(.*\)| + __always_inline__| + __assume_aligned__\(.*\)| + __cold__| + __const__| + __copy__\(.*\)| + __designated_init__| + __externally_visible__| + __fallthrough__| + __gnu_inline__| + __malloc__| + __mode__\(.*\)| + __no_caller_saved_registers__| + __noclone__| + __noinline__| + __nonstring__| + __noreturn__| + __packed__| + __pure__| + __used__ + }x; -# Check for __attribute__ aligned, prefer __aligned - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*aligned/) { - WARN("PREFER_ALIGNED", - "__aligned(size) is preferred over __attribute__((aligned(size)))\n" . $herecurr); - } + my %attr_replace = ( + "__alias__" => "__alias", + "__aligned__" => "__aligned_largest", + "__aligned__(" => "__aligned", + "__always_inline__" => "__always_inline", + "__assume_aligned__(" => "__assume_aligned", + "__cold__" => "__cold", + "__const__" => "__const", + "__copy__(" => "__copy", + "__designated_init__" => "__designated_init", + "__externally_visible__" => "__visible", + "__fallthrough__" => "fallthrough", + "__gnu_inline__" => "__gnu_inline", + "__malloc__" => "__malloc", + "__mode__(" => "__mode", + "__no_caller_saved_registers__" => "__no_caller_saved_registers", + "__noclone__" => "__noclone", + "__noinline__" => "noinline", + "__nonstring__" => "__nonstring", + "__noreturn__" => "__noreturn", + "__packed__" => "__packed", + "__pure__" => "__pure", + "__used__" => "__used" + ); + + if ($attr =~/^($attr_list)/) { + my $old = $1; + if ($old =~ /^(__.+__\()(.*)\)/) { + my $new = $attr_replace{$1}; + WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "$new($2) is preffered over __attribute__(($old))\n" . $herecurr); + } else { + my $new = $attr_replace{$old}; + WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "$new is preffered over __attribute__(($old))\n" . $herecurr); + } + } -# Check for __attribute__ section, prefer __section - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(.*_*section_*\s*\(\s*("[^"]*")/) { - my $old = substr($rawline, $-[1], $+[1] - $-[1]); - my $new = substr($old, 1, -1); - if (WARN("PREFER_SECTION", - "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + # Check for __attribute__ format(printf, prefer __printf + if ($attr =~ /^_*format_*\s*\(\s*printf/) { + if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; + + } } - } -# Check for __attribute__ format(printf, prefer __printf - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf/) { - if (WARN("PREFER_PRINTF", - "__printf(string-index, first-to-check) is preferred over __attribute__((format(printf, string-index, first-to-check)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*printf\s*,\s*(.*)\)\s*\)\s*\)/"__printf(" . trim($1) . ")"/ex; + # Check for __attribute__ format(scanf, prefer __scanf + if ($attr =~ /^_*format_*\s*\(\s*scanf\b/) { + if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; + } + } + # Check for __attribute__ section, prefer __section + if ($attr =~ /^_*section_*\s*\(\s*("[^"]*")/) { + my $old = substr($rawline, $-[1], $+[1] - $-[1]); + my $new = substr($old, 1, -1); + if (WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + $fix) { + $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; + } } - } -# Check for __attribute__ format(scanf, prefer __scanf - if ($realfile !~ m@\binclude/uapi/@ && - $line =~ /\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\b/) { - if (WARN("PREFER_SCANF", - "__scanf(string-index, first-to-check) is preferred over __attribute__((format(scanf, string-index, first-to-check)))\n" . $herecurr) && - $fix) { - $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*format\s*\(\s*scanf\s*,\s*(.*)\)\s*\)\s*\)/"__scanf(" . trim($1) . ")"/ex; + # Check for __attribute__ unused, prefer __always_unused or __maybe_unused + if ($attr =~ /^_*unused_*/) { + WARN("PREFER_DEFINED_ATTRIBUTE_MACRO", + "__always_unused or __maybe_unused is preferred over __attribute__((__unused__))\n" . $herecurr); } } -- 2.27.0
Powered by blists - more mailing lists