6972 lines · 205.6 KB · Perl
RawDownload
			}		} # check for data_race without a comment.		if ($line =~ /\bdata_race\s*\(/) {			if (!ctx_has_comment($first_line, $linenr)) {				WARN("DATA_RACE",				     "data_race without comment\n" . $herecurr);			}		} # check of hardware specific defines		if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) {			CHK("ARCH_DEFINES",			    "architecture specific defines should be avoided\n" .  $herecurr);		} # check that the storage class is not after a type		if ($line =~ /\b($Type)\s+($Storage)\b/) {			WARN("STORAGE_CLASS",			     "storage class '$2' should be located before type '$1'\n" . $herecurr);		}# Check that the storage class is at the beginning of a declaration		if ($line =~ /\b$Storage\b/ &&		    $line !~ /^.\s*$Storage/ &&		    $line =~ /^.\s*(.+?)\$Storage\s/ &&		    $1 !~ /[\,\)]\s*$/) {			WARN("STORAGE_CLASS",			     "storage class should be at the beginning of the declaration\n" . $herecurr);		} # check the location of the inline attribute, that it is between# storage class and type.		if ($line =~ /\b$Type\s+$Inline\b/ ||		    $line =~ /\b$Inline\s+$Storage\b/) {			ERROR("INLINE_LOCATION",			      "inline keyword should sit between storage class and type\n" . $herecurr);		} # Check for __inline__ and __inline, prefer inline		if ($realfile !~ m@\binclude/uapi/@ &&		    $line =~ /\b(__inline__|__inline)\b/) {			if (WARN("INLINE",				 "plain inline is preferred over $1\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\b(__inline__|__inline)\b/inline/; 			}		} # Check for __attribute__ packed, prefer __packed		if ($realfile !~ m@\binclude/uapi/@ &&		    $line =~ /\b__attribute__\s*\(\s*\(.*\bpacked\b/) {			WARN("PREFER_PACKED",			     "__packed is preferred over __attribute__((packed))\n" . $herecurr);		} # 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);		} # 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 ($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 ($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__ weak, or __weak declarations (may have link issues)		if ($perl_version_ok &&		    $line =~ /(?:$Declare|$DeclareMisordered)\s*$Ident\s*$balanced_parens\s*(?:$Attribute)?\s*;/ &&		    ($line =~ /\b__attribute__\s*\(\s*\(.*\bweak\b/ ||		     $line =~ /\b__weak\b/)) {			ERROR("WEAK_DECLARATION",			      "Using weak declarations can have unintended link defects\n" . $herecurr);		} # check for c99 types like uint8_t used outside of uapi/ and tools/		if ($realfile !~ m@\binclude/uapi/@ &&		    $realfile !~ m@\btools/@ &&		    $line =~ /\b($Declare)\s*$Ident\s*[=;,\[]/) {			my $type = $1;			if ($type =~ /\b($typeC99Typedefs)\b/) {				$type = $1;				my $kernel_type = 'u';				$kernel_type = 's' if ($type =~ /^_*[si]/);				$type =~ /(\d+)/;				$kernel_type .= $1;				if (CHK("PREFER_KERNEL_TYPES",					"Prefer kernel type '$kernel_type' over '$type'\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\b$type\b/$kernel_type/;				}			}		} # check for cast of C90 native int or longer types constants		if ($line =~ /(\(\s*$C90_int_types\s*\)\s*)($Constant)\b/) {			my $cast = $1;			my $const = $2;			if (WARN("TYPECAST_INT_CONSTANT",				 "Unnecessary typecast of c90 int constant\n" . $herecurr) &&			    $fix) {				my $suffix = "";				my $newconst = $const;				$newconst =~ s/${Int_type}$//;				$suffix .= 'U' if ($cast =~ /\bunsigned\b/);				if ($cast =~ /\blong\s+long\b/) {					$suffix .= 'LL';				} elsif ($cast =~ /\blong\b/) {					$suffix .= 'L';				}				$fixed[$fixlinenr] =~ s/\Q$cast\E$const\b/$newconst$suffix/;			}		} # check for sizeof(&)		if ($line =~ /\bsizeof\s*\(\s*\&/) {			WARN("SIZEOF_ADDRESS",			     "sizeof(& should be avoided\n" . $herecurr);		} # check for sizeof without parenthesis		if ($line =~ /\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/) {			if (WARN("SIZEOF_PARENTHESIS",				 "sizeof $1 should be sizeof($1)\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\bsizeof\s+((?:\*\s*|)$Lval|$Type(?:\s+$Lval|))/"sizeof(" . trim($1) . ")"/ex;			}		} # check for struct spinlock declarations		if ($line =~ /^.\s*\bstruct\s+spinlock\s+\w+\s*;/) {			WARN("USE_SPINLOCK_T",			     "struct spinlock should be spinlock_t\n" . $herecurr);		} # check for seq_printf uses that could be seq_puts		if ($sline =~ /\bseq_printf\s*\(.*"\s*\)\s*;\s*$/) {			my $fmt = get_quoted_string($line, $rawline);			$fmt =~ s/%%//g;			if ($fmt !~ /%/) {				if (WARN("PREFER_SEQ_PUTS",					 "Prefer seq_puts to seq_printf\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\bseq_printf\b/seq_puts/;				}			}		} # check for vsprintf extension %p<foo> misuses		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+(?![^\{]*\{\s*).*\b(\w+)\s*\(.*$String\s*,/s &&		    $1 !~ /^_*volatile_*$/) {			my $stat_real; 			my $lc = $stat =~ tr@\n@@;			$lc = $lc + $linenr;		        for (my $count = $linenr; $count <= $lc; $count++) {				my $specifier;				my $extension;				my $qualifier;				my $bad_specifier = "";				my $fmt = get_quoted_string($lines[$count - 1], raw_line($count, 0));				$fmt =~ s/%%//g; 				while ($fmt =~ /(\%[\*\d\.]*p(\w)(\w*))/g) {					$specifier = $1;					$extension = $2;					$qualifier = $3;					if ($extension !~ /[SsBKRraEehMmIiUDdgVCbGNOxtf]/ ||					    ($extension eq "f" &&					     defined $qualifier && $qualifier !~ /^w/)) {						$bad_specifier = $specifier;						last;					}					if ($extension eq "x" && !defined($stat_real)) {						if (!defined($stat_real)) {							$stat_real = get_stat_real($linenr, $lc);						}						WARN("VSPRINTF_SPECIFIER_PX",						     "Using vsprintf specifier '\%px' potentially exposes the kernel memory layout, if you don't really need the address please consider using '\%p'.\n" . "$here\n$stat_real\n");					}				}				if ($bad_specifier ne "") {					my $stat_real = get_stat_real($linenr, $lc);					my $ext_type = "Invalid";					my $use = "";					if ($bad_specifier =~ /p[Ff]/) {						$use = " - use %pS instead";						$use =~ s/pS/ps/ if ($bad_specifier =~ /pf/);					} 					WARN("VSPRINTF_POINTER_EXTENSION",					     "$ext_type vsprintf pointer extension '$bad_specifier'$use\n" . "$here\n$stat_real\n");				}			}		} # Check for misused memsets		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*$FuncArg\s*\)/) { 			my $ms_addr = $2;			my $ms_val = $7;			my $ms_size = $12; 			if ($ms_size =~ /^(0x|)0$/i) {				ERROR("MEMSET",				      "memset to 0's uses 0 as the 2nd argument, not the 3rd\n" . "$here\n$stat\n");			} elsif ($ms_size =~ /^(0x|)1$/i) {				WARN("MEMSET",				     "single byte memset is suspicious. Swapped 2nd/3rd argument?\n" . "$here\n$stat\n");			}		} # Check for memcpy(foo, bar, ETH_ALEN) that could be ether_addr_copy(foo, bar)#		if ($perl_version_ok &&#		    defined $stat &&#		    $stat =~ /^\+(?:.*?)\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {#			if (WARN("PREFER_ETHER_ADDR_COPY",#				 "Prefer ether_addr_copy() over memcpy() if the Ethernet addresses are __aligned(2)\n" . "$here\n$stat\n") &&#			    $fix) {#				$fixed[$fixlinenr] =~ s/\bmemcpy\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/ether_addr_copy($2, $7)/;#			}#		} # Check for memcmp(foo, bar, ETH_ALEN) that could be ether_addr_equal*(foo, bar)#		if ($perl_version_ok &&#		    defined $stat &&#		    $stat =~ /^\+(?:.*?)\bmemcmp\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {#			WARN("PREFER_ETHER_ADDR_EQUAL",#			     "Prefer ether_addr_equal() or ether_addr_equal_unaligned() over memcmp()\n" . "$here\n$stat\n")#		} # check for memset(foo, 0x0, ETH_ALEN) that could be eth_zero_addr# check for memset(foo, 0xFF, ETH_ALEN) that could be eth_broadcast_addr#		if ($perl_version_ok &&#		    defined $stat &&#		    $stat =~ /^\+(?:.*?)\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\,\s*ETH_ALEN\s*\)/) {##			my $ms_val = $7;##			if ($ms_val =~ /^(?:0x|)0+$/i) {#				if (WARN("PREFER_ETH_ZERO_ADDR",#					 "Prefer eth_zero_addr over memset()\n" . "$here\n$stat\n") &&#				    $fix) {#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_zero_addr($2)/;#				}#			} elsif ($ms_val =~ /^(?:0xff|255)$/i) {#				if (WARN("PREFER_ETH_BROADCAST_ADDR",#					 "Prefer eth_broadcast_addr() over memset()\n" . "$here\n$stat\n") &&#				    $fix) {#					$fixed[$fixlinenr] =~ s/\bmemset\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*,\s*ETH_ALEN\s*\)/eth_broadcast_addr($2)/;#				}#			}#		} # typecasts on min/max could be min_t/max_t		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+(?:.*?)\b(min|max)\s*\(\s*$FuncArg\s*,\s*$FuncArg\s*\)/) {			if (defined $2 || defined $7) {				my $call = $1;				my $cast1 = deparenthesize($2);				my $arg1 = $3;				my $cast2 = deparenthesize($7);				my $arg2 = $8;				my $cast; 				if ($cast1 ne "" && $cast2 ne "" && $cast1 ne $cast2) {					$cast = "$cast1 or $cast2";				} elsif ($cast1 ne "") {					$cast = $cast1;				} else {					$cast = $cast2;				}				WARN("MINMAX",				     "$call() should probably be ${call}_t($cast, $arg1, $arg2)\n" . "$here\n$stat\n");			}		} # check usleep_range arguments		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+(?:.*?)\busleep_range\s*\(\s*($FuncArg)\s*,\s*($FuncArg)\s*\)/) {			my $min = $1;			my $max = $7;			if ($min eq $max) {				WARN("USLEEP_RANGE",				     "usleep_range should not use min == max args; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");			} elsif ($min =~ /^\d+$/ && $max =~ /^\d+$/ &&				 $min > $max) {				WARN("USLEEP_RANGE",				     "usleep_range args reversed, use min then max; see Documentation/timers/timers-howto.rst\n" . "$here\n$stat\n");			}		} # check for naked sscanf		if ($perl_version_ok &&		    defined $stat &&		    $line =~ /\bsscanf\b/ &&		    ($stat !~ /$Ident\s*=\s*sscanf\s*$balanced_parens/ &&		     $stat !~ /\bsscanf\s*$balanced_parens\s*(?:$Compare)/ &&		     $stat !~ /(?:$Compare)\s*\bsscanf\s*$balanced_parens/)) {			my $lc = $stat =~ tr@\n@@;			$lc = $lc + $linenr;			my $stat_real = get_stat_real($linenr, $lc);			WARN("NAKED_SSCANF",			     "unchecked sscanf return value\n" . "$here\n$stat_real\n");		} # check for simple sscanf that should be kstrto<foo>		if ($perl_version_ok &&		    defined $stat &&		    $line =~ /\bsscanf\b/) {			my $lc = $stat =~ tr@\n@@;			$lc = $lc + $linenr;			my $stat_real = get_stat_real($linenr, $lc);			if ($stat_real =~ /\bsscanf\b\s*\(\s*$FuncArg\s*,\s*("[^"]+")/) {				my $format = $6;				my $count = $format =~ tr@%@%@;				if ($count == 1 &&				    $format =~ /^"\%(?i:ll[udxi]|[udxi]ll|ll|[hl]h?[udxi]|[udxi][hl]h?|[hl]h?|[udxi])"$/) {					WARN("SSCANF_TO_KSTRTO",					     "Prefer kstrto<type> to single variable sscanf\n" . "$here\n$stat_real\n");				}			}		} # check for new externs in .h files.		if ($realfile =~ /\.h$/ &&		    $line =~ /^\+\s*(extern\s+)$Type\s*$Ident\s*\(/s) {			if (CHK("AVOID_EXTERNS",				"extern prototypes should be avoided in .h files\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/(.*)\bextern\b\s*(.*)/$1$2/;			}		} # check for new externs in .c files.		if ($realfile =~ /\.c$/ && defined $stat &&		    $stat =~ /^.\s*(?:extern\s+)?$Type\s+($Ident)(\s*)\(/s)		{			my $function_name = $1;			my $paren_space = $2; 			my $s = $stat;			if (defined $cond) {				substr($s, 0, length($cond), '');			}			if ($s =~ /^\s*;/)			{				WARN("AVOID_EXTERNS",				     "externs should be avoided in .c files\n" .  $herecurr);			} 			if ($paren_space =~ /\n/) {				WARN("FUNCTION_ARGUMENTS",				     "arguments for function declarations should follow identifier\n" . $herecurr);			} 		} elsif ($realfile =~ /\.c$/ && defined $stat &&		    $stat =~ /^.\s*extern\s+/)		{			WARN("AVOID_EXTERNS",			     "externs should be avoided in .c files\n" .  $herecurr);		} # check for function declarations that have arguments without identifier names		if (defined $stat &&		    $stat =~ /^.\s*(?:extern\s+)?$Type\s*(?:$Ident|\(\s*\*\s*$Ident\s*\))\s*\(\s*([^{]+)\s*\)\s*;/s &&		    $1 ne "void") {			my $args = trim($1);			while ($args =~ m/\s*($Type\s*(?:$Ident|\(\s*\*\s*$Ident?\s*\)\s*$balanced_parens)?)/g) {				my $arg = trim($1);				if ($arg =~ /^$Type$/ && $arg !~ /enum\s+$Ident$/) {					WARN("FUNCTION_ARGUMENTS",					     "function definition argument '$arg' should also have an identifier name\n" . $herecurr);				}			}		} # check for function definitions		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^.\s*(?:$Storage\s+)?$Type\s*($Ident)\s*$balanced_parens\s*{/s) {			$context_function = $1; # check for multiline function definition with misplaced open brace			my $ok = 0;			my $cnt = statement_rawlines($stat);			my $herectx = $here . "\n";			for (my $n = 0; $n < $cnt; $n++) {				my $rl = raw_line($linenr, $n);				$herectx .=  $rl . "\n";				$ok = 1 if ($rl =~ /^[ \+]\{/);				$ok = 1 if ($rl =~ /\{/ && $n == 0);				last if $rl =~ /^[ \+].*\{/;			}			if (!$ok) {				ERROR("OPEN_BRACE",				      "open brace '{' following function definitions go on the next line\n" . $herectx);			}		} # checks for new __setup's		if ($rawline =~ /\b__setup\("([^"]*)"/) {			my $name = $1; 			if (!grep(/$name/, @setup_docs)) {				CHK("UNDOCUMENTED_SETUP",				    "__setup appears un-documented -- check Documentation/admin-guide/kernel-parameters.txt\n" . $herecurr);			}		} # check for pointless casting of alloc functions		if ($line =~ /\*\s*\)\s*$allocFunctions\b/) {			WARN("UNNECESSARY_CASTS",			     "unnecessary cast may hide bugs, see http://c-faq.com/malloc/mallocnocast.html\n" . $herecurr);		} # alloc style# p = alloc(sizeof(struct foo), ...) should be p = alloc(sizeof(*p), ...)		if ($perl_version_ok &&		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k|v)[mz]alloc(?:_node)?)\s*\(\s*(sizeof\s*\(\s*struct\s+$Lval\s*\))/) {			CHK("ALLOC_SIZEOF_STRUCT",			    "Prefer $3(sizeof(*$1)...) over $3($4...)\n" . $herecurr);		} # check for k[mz]alloc with multiplies that could be kmalloc_array/kcalloc		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {			my $oldfunc = $3;			my $a1 = $4;			my $a2 = $10;			my $newfunc = "kmalloc_array";			$newfunc = "kcalloc" if ($oldfunc eq "kzalloc");			my $r1 = $a1;			my $r2 = $a2;			if ($a1 =~ /^sizeof\s*\S/) {				$r1 = $a2;				$r2 = $a1;			}			if ($r1 !~ /^sizeof\b/ && $r2 =~ /^sizeof\s*\S/ &&			    !($r1 =~ /^$Constant$/ || $r1 =~ /^[A-Z_][A-Z0-9_]*$/)) {				my $cnt = statement_rawlines($stat);				my $herectx = get_stat_here($linenr, $cnt, $here); 				if (WARN("ALLOC_WITH_MULTIPLY",					 "Prefer $newfunc over $oldfunc with multiply\n" . $herectx) &&				    $cnt == 1 &&				    $fix) {					$fixed[$fixlinenr] =~ s/\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*(k[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)/$1 . ' = ' . "$newfunc(" . trim($r1) . ', ' . trim($r2)/e;				}			}		} # check for krealloc arg reuse		if ($perl_version_ok &&		    $line =~ /\b($Lval)\s*\=\s*(?:$balanced_parens)?\s*krealloc\s*\(\s*($Lval)\s*,/ &&		    $1 eq $3) {			WARN("KREALLOC_ARG_REUSE",			     "Reusing the krealloc arg is almost always a bug\n" . $herecurr);		} # check for alloc argument mismatch		if ($line =~ /\b(kcalloc|kmalloc_array)\s*\(\s*sizeof\b/) {

Lines 6001–6500 of 6972. Previous lines