7586 lines · 225.6 KB · Perl
RawDownload
				$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 (kv|k)[mz]alloc with multiplies that could be kmalloc_array/kvmalloc_array/kvcalloc/kcalloc		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+\s*($Lval)\s*\=\s*(?:$balanced_parens)?\s*((?:kv|k)[mz]alloc)\s*\(\s*($FuncArg)\s*\*\s*($FuncArg)\s*,/) {			my $oldfunc = $3;			my $a1 = $4;			my $a2 = $10;			my $newfunc = "kmalloc_array";			$newfunc = "kvmalloc_array" if ($oldfunc eq "kvmalloc");			$newfunc = "kvcalloc" if ($oldfunc eq "kvzalloc");			$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*((?:kv|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((?:devm_)?(?:kcalloc|kmalloc_array))\s*\(\s*sizeof\b/) {			WARN("ALLOC_ARRAY_ARGS",			     "$1 uses number as first arg, sizeof is generally wrong\n" . $herecurr);		} # check for multiple semicolons		if ($line =~ /;\s*;\s*$/) {			if (WARN("ONE_SEMICOLON",				 "Statements terminations use 1 semicolon\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/(\s*;\s*){2,}$/;/g;			}		} # check for #defines like: 1 << <digit> that could be BIT(digit), it is not exported to uapi		if ($realfile !~ m@^include/uapi/@ &&		    $line =~ /#\s*define\s+\w+\s+\(?\s*1\s*([ulUL]*)\s*\<\<\s*(?:\d+|$Ident)\s*\)?/) {			my $ull = "";			$ull = "_ULL" if (defined($1) && $1 =~ /ll/i);			if (CHK("BIT_MACRO",				"Prefer using the BIT$ull macro\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\(?\s*1\s*[ulUL]*\s*<<\s*(\d+|$Ident)\s*\)?/BIT${ull}($1)/;			}		} # check for IS_ENABLED() without CONFIG_<FOO> ($rawline for comments too)		if ($rawline =~ /\bIS_ENABLED\s*\(\s*(\w+)\s*\)/ && $1 !~ /^${CONFIG_}/) {			WARN("IS_ENABLED_CONFIG",			     "IS_ENABLED($1) is normally used as IS_ENABLED(${CONFIG_}$1)\n" . $herecurr);		} # check for #if defined CONFIG_<FOO> || defined CONFIG_<FOO>_MODULE		if ($line =~ /^\+\s*#\s*if\s+defined(?:\s*\(?\s*|\s+)(${CONFIG_}[A-Z_]+)\s*\)?\s*\|\|\s*defined(?:\s*\(?\s*|\s+)\1_MODULE\s*\)?\s*$/) {			my $config = $1;			if (WARN("PREFER_IS_ENABLED",				 "Prefer IS_ENABLED(<FOO>) to ${CONFIG_}<FOO> || ${CONFIG_}<FOO>_MODULE\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] = "\+#if IS_ENABLED($config)";			}		} # check for /* fallthrough */ like comment, prefer fallthrough;		my @fallthroughs = (			'fallthrough',			'@fallthrough@',			'lint -fallthrough[ \t]*',			'intentional(?:ly)?[ \t]*fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)',			'(?:else,?\s*)?FALL(?:S | |-)?THR(?:OUGH|U|EW)[ \t.!]*(?:-[^\n\r]*)?',			'Fall(?:(?:s | |-)[Tt]|t)hr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',			'fall(?:s | |-)?thr(?:ough|u|ew)[ \t.!]*(?:-[^\n\r]*)?',		    );		if ($raw_comment ne '') {			foreach my $ft (@fallthroughs) {				if ($raw_comment =~ /$ft/) {					my $msg_level = \&WARN;					$msg_level = \&CHK if ($file);					&{$msg_level}("PREFER_FALLTHROUGH",						      "Prefer 'fallthrough;' over fallthrough comment\n" . $herecurr);					last;				}			}		} # check for switch/default statements without a break;		if ($perl_version_ok &&		    defined $stat &&		    $stat =~ /^\+[$;\s]*(?:case[$;\s]+\w+[$;\s]*:[$;\s]*|)*[$;\s]*\bdefault[$;\s]*:[$;\s]*;/g) {			my $cnt = statement_rawlines($stat);			my $herectx = get_stat_here($linenr, $cnt, $here); 			WARN("DEFAULT_NO_BREAK",			     "switch default: should use break\n" . $herectx);		} # check for gcc specific __FUNCTION__		if ($line =~ /\b__FUNCTION__\b/) {			if (WARN("USE_FUNC",				 "__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\b__FUNCTION__\b/__func__/g;			}		} # check for uses of __DATE__, __TIME__, __TIMESTAMP__		while ($line =~ /\b(__(?:DATE|TIME|TIMESTAMP)__)\b/g) {			ERROR("DATE_TIME",			      "Use of the '$1' macro makes the build non-deterministic\n" . $herecurr);		} # check for use of yield()		if ($line =~ /\byield\s*\(\s*\)/) {			WARN("YIELD",			     "Using yield() is generally wrong. See yield() kernel-doc (sched/core.c)\n"  . $herecurr);		} # check for comparisons against true and false		if ($line =~ /\+\s*(.*?)\b(true|false|$Lval)\s*(==|\!=)\s*(true|false|$Lval)\b(.*)$/i) {			my $lead = $1;			my $arg = $2;			my $test = $3;			my $otype = $4;			my $trail = $5;			my $op = "!"; 			($arg, $otype) = ($otype, $arg) if ($arg =~ /^(?:true|false)$/i); 			my $type = lc($otype);			if ($type =~ /^(?:true|false)$/) {				if (("$test" eq "==" && "$type" eq "true") ||				    ("$test" eq "!=" && "$type" eq "false")) {					$op = "";				} 				CHK("BOOL_COMPARISON",				    "Using comparison to $otype is error prone\n" . $herecurr); ## maybe suggesting a correct construct would better##				    "Using comparison to $otype is error prone.  Perhaps use '${lead}${op}${arg}${trail}'\n" . $herecurr); 			}		} # check for semaphores initialized locked		if ($line =~ /^.\s*sema_init.+,\W?0\W?\)/) {			WARN("CONSIDER_COMPLETION",			     "consider using a completion\n" . $herecurr);		} # recommend kstrto* over simple_strto* and strict_strto*		if ($line =~ /\b((simple|strict)_(strto(l|ll|ul|ull)))\s*\(/) {			WARN("CONSIDER_KSTRTO",			     "$1 is obsolete, use k$3 instead\n" . $herecurr);		} # check for __initcall(), use device_initcall() explicitly or more appropriate function please		if ($line =~ /^.\s*__initcall\s*\(/) {			WARN("USE_DEVICE_INITCALL",			     "please use device_initcall() or more appropriate function instead of __initcall() (see include/linux/init.h)\n" . $herecurr);		} # check for spin_is_locked(), suggest lockdep instead		if ($line =~ /\bspin_is_locked\(/) {			WARN("USE_LOCKDEP",			     "Where possible, use lockdep_assert_held instead of assertions based on spin_is_locked\n" . $herecurr);		} # check for deprecated apis		if ($line =~ /\b($deprecated_apis_search)\b\s*\(/) {			my $deprecated_api = $1;			my $new_api = $deprecated_apis{$deprecated_api};			WARN("DEPRECATED_API",			     "Deprecated use of '$deprecated_api', prefer '$new_api' instead\n" . $herecurr);		} # check for various structs that are normally const (ops, kgdb, device_tree)# and avoid what seem like struct definitions 'struct foo {'		if (defined($const_structs) &&		    $line !~ /\bconst\b/ &&		    $line =~ /\bstruct\s+($const_structs)\b(?!\s*\{)/) {			WARN("CONST_STRUCT",			     "struct $1 should normally be const\n" . $herecurr);		} # use of NR_CPUS is usually wrong# ignore definitions of NR_CPUS and usage to define arrays as likely right# ignore designated initializers using NR_CPUS		if ($line =~ /\bNR_CPUS\b/ &&		    $line !~ /^.\s*\s*#\s*if\b.*\bNR_CPUS\b/ &&		    $line !~ /^.\s*\s*#\s*define\b.*\bNR_CPUS\b/ &&		    $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/ &&		    $line !~ /\[[^\]]*\.\.\.[^\]]*NR_CPUS[^\]]*\]/ &&		    $line !~ /\[[^\]]*NR_CPUS[^\]]*\.\.\.[^\]]*\]/ &&		    $line !~ /^.\s*\.\w+\s*=\s*.*\bNR_CPUS\b/)		{			WARN("NR_CPUS",			     "usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);		} # Use of __ARCH_HAS_<FOO> or ARCH_HAVE_<BAR> is wrong.		if ($line =~ /\+\s*#\s*define\s+((?:__)?ARCH_(?:HAS|HAVE)\w*)\b/) {			ERROR("DEFINE_ARCH_HAS",			      "#define of '$1' is wrong - use Kconfig variables or standard guards instead\n" . $herecurr);		} # likely/unlikely comparisons similar to "(likely(foo) > 0)"		if ($perl_version_ok &&		    $line =~ /\b((?:un)?likely)\s*\(\s*$FuncArg\s*\)\s*$Compare/) {			WARN("LIKELY_MISUSE",			     "Using $1 should generally have parentheses around the comparison\n" . $herecurr);		} # return sysfs_emit(foo, fmt, ...) fmt without newline		if ($line =~ /\breturn\s+sysfs_emit\s*\(\s*$FuncArg\s*,\s*($String)/ &&		    substr($rawline, $-[6], $+[6] - $-[6]) !~ /\\n"$/) {			my $offset = $+[6] - 1;			if (WARN("SYSFS_EMIT",				 "return sysfs_emit(...) formats should include a terminating newline\n" . $herecurr) &&			    $fix) {				substr($fixed[$fixlinenr], $offset, 0) = '\\n';			}		} # nested likely/unlikely calls		if ($line =~ /\b(?:(?:un)?likely)\s*\(\s*!?\s*(IS_ERR(?:_OR_NULL|_VALUE)?|WARN)/) {			WARN("LIKELY_MISUSE",			     "nested (un)?likely() calls, $1 already uses unlikely() internally\n" . $herecurr);		} # whine mightly about in_atomic		if ($line =~ /\bin_atomic\s*\(/) {			if ($realfile =~ m@^drivers/@) {				ERROR("IN_ATOMIC",				      "do not use in_atomic in drivers\n" . $herecurr);			} elsif ($realfile !~ m@^kernel/@) {				WARN("IN_ATOMIC",				     "use of in_atomic() is incorrect outside core kernel code\n" . $herecurr);			}		} # check for lockdep_set_novalidate_class		if ($line =~ /^.\s*lockdep_set_novalidate_class\s*\(/ ||		    $line =~ /__lockdep_no_validate__\s*\)/ ) {			if ($realfile !~ m@^kernel/lockdep@ &&			    $realfile !~ m@^include/linux/lockdep@ &&			    $realfile !~ m@^drivers/base/core@) {				ERROR("LOCKDEP",				      "lockdep_no_validate class is reserved for device->mutex.\n" . $herecurr);			}		} 		if ($line =~ /debugfs_create_\w+.*\b$mode_perms_world_writable\b/ ||		    $line =~ /DEVICE_ATTR.*\b$mode_perms_world_writable\b/) {			WARN("EXPORTED_WORLD_WRITABLE",			     "Exporting world writable files is usually an error. Consider more restrictive permissions.\n" . $herecurr);		} # check for DEVICE_ATTR uses that could be DEVICE_ATTR_<FOO># and whether or not function naming is typical and if# DEVICE_ATTR permissions uses are unusual too		if ($perl_version_ok &&		    defined $stat &&		    $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*\)/) {			my $var = $1;			my $perms = $2;			my $show = $3;			my $store = $4;			my $octal_perms = perms_to_octal($perms);			if ($show =~ /^${var}_show$/ &&			    $store =~ /^${var}_store$/ &&			    $octal_perms eq "0644") {				if (WARN("DEVICE_ATTR_RW",					 "Use DEVICE_ATTR_RW\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*$store\s*\)/DEVICE_ATTR_RW(${var})/;				}			} elsif ($show =~ /^${var}_show$/ &&				 $store =~ /^NULL$/ &&				 $octal_perms eq "0444") {				if (WARN("DEVICE_ATTR_RO",					 "Use DEVICE_ATTR_RO\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*$show\s*,\s*NULL\s*\)/DEVICE_ATTR_RO(${var})/;				}			} elsif ($show =~ /^NULL$/ &&				 $store =~ /^${var}_store$/ &&				 $octal_perms eq "0200") {				if (WARN("DEVICE_ATTR_WO",					 "Use DEVICE_ATTR_WO\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\bDEVICE_ATTR\s*\(\s*$var\s*,\s*\Q$perms\E\s*,\s*NULL\s*,\s*$store\s*\)/DEVICE_ATTR_WO(${var})/;				}			} elsif ($octal_perms eq "0644" ||				 $octal_perms eq "0444" ||				 $octal_perms eq "0200") {				my $newshow = "$show";				$newshow = "${var}_show" if ($show ne "NULL" && $show ne "${var}_show");				my $newstore = $store;				$newstore = "${var}_store" if ($store ne "NULL" && $store ne "${var}_store");				my $rename = "";				if ($show ne $newshow) {					$rename .= " '$show' to '$newshow'";				}				if ($store ne $newstore) {					$rename .= " '$store' to '$newstore'";				}				WARN("DEVICE_ATTR_FUNCTIONS",				     "Consider renaming function(s)$rename\n" . $herecurr);			} else {				WARN("DEVICE_ATTR_PERMS",				     "DEVICE_ATTR unusual permissions '$perms' used\n" . $herecurr);			}		} # Mode permission misuses where it seems decimal should be octal# This uses a shortcut match to avoid unnecessary uses of a slow foreach loop# o Ignore module_param*(...) uses with a decimal 0 permission as that has a#   specific definition of not visible in sysfs.# o Ignore proc_create*(...) uses with a decimal 0 permission as that means#   use the default permissions		if ($perl_version_ok &&		    defined $stat &&		    $line =~ /$mode_perms_search/) {			foreach my $entry (@mode_permission_funcs) {				my $func = $entry->[0];				my $arg_pos = $entry->[1]; 				my $lc = $stat =~ tr@\n@@;				$lc = $lc + $linenr;				my $stat_real = get_stat_real($linenr, $lc); 				my $skip_args = "";				if ($arg_pos > 1) {					$arg_pos--;					$skip_args = "(?:\\s*$FuncArg\\s*,\\s*){$arg_pos,$arg_pos}";				}				my $test = "\\b$func\\s*\\(${skip_args}($FuncArg(?:\\|\\s*$FuncArg)*)\\s*[,\\)]";				if ($stat =~ /$test/) {					my $val = $1;					$val = $6 if ($skip_args ne "");					if (!($func =~ /^(?:module_param|proc_create)/ && $val eq "0") &&					    (($val =~ /^$Int$/ && $val !~ /^$Octal$/) ||					     ($val =~ /^$Octal$/ && length($val) ne 4))) {						ERROR("NON_OCTAL_PERMISSIONS",						      "Use 4 digit octal (0777) not decimal permissions\n" . "$here\n" . $stat_real);					}					if ($val =~ /^$Octal$/ && (oct($val) & 02)) {						ERROR("EXPORTED_WORLD_WRITABLE",						      "Exporting writable files is usually an error. Consider more restrictive permissions.\n" . "$here\n" . $stat_real);					}				}			}		} # check for uses of S_<PERMS> that could be octal for readability		while ($line =~ m{\b($multi_mode_perms_string_search)\b}g) {			my $oval = $1;			my $octal = perms_to_octal($oval);			if (WARN("SYMBOLIC_PERMS",				 "Symbolic permissions '$oval' are not preferred. Consider using octal permissions '$octal'.\n" . $herecurr) &&			    $fix) {				$fixed[$fixlinenr] =~ s/\Q$oval\E/$octal/;			}		} # validate content of MODULE_LICENSE against list from include/linux/module.h		if ($line =~ /\bMODULE_LICENSE\s*\(\s*($String)\s*\)/) {			my $extracted_string = get_quoted_string($line, $rawline);			my $valid_licenses = qr{						GPL|						GPL\ v2|						GPL\ and\ additional\ rights|						Dual\ BSD/GPL|						Dual\ MIT/GPL|						Dual\ MPL/GPL|						Proprietary					}x;			if ($extracted_string !~ /^"(?:$valid_licenses)"$/x) {				WARN("MODULE_LICENSE",				     "unknown module license " . $extracted_string . "\n" . $herecurr);			}			if (!$file && $extracted_string eq '"GPL v2"') {				if (WARN("MODULE_LICENSE",				     "Prefer \"GPL\" over \"GPL v2\" - see commit bf7fbeeae6db (\"module: Cure the MODULE_LICENSE \"GPL\" vs. \"GPL v2\" bogosity\")\n" . $herecurr) &&				    $fix) {					$fixed[$fixlinenr] =~ s/\bMODULE_LICENSE\s*\(\s*"GPL v2"\s*\)/MODULE_LICENSE("GPL")/;				}			}		} # check for sysctl duplicate constants		if ($line =~ /\.extra[12]\s*=\s*&(zero|one|int_max)\b/) {			WARN("DUPLICATED_SYSCTL_CONST",				"duplicated sysctl range checking value '$1', consider using the shared one in include/linux/sysctl.h\n" . $herecurr);		}	} 	# If we have no input at all, then there is nothing to report on	# so just keep quiet.	if ($#rawlines == -1) {		exit(0);	} 	# In mailback mode only produce a report in the negative, for	# things that appear to be patches.	if ($mailback && ($clean == 1 || !$is_patch)) {		exit(0);	} 	# This is not a patch, and we are in 'no-patch' mode so	# just keep quiet.	if (!$chk_patch && !$is_patch) {		exit(0);	} 	if (!$is_patch && $filename !~ /cover-letter\.patch$/) {		ERROR("NOT_UNIFIED_DIFF",		      "Does not appear to be a unified-diff format patch\n");	}	if ($is_patch && $has_commit_log && $chk_signoff) {		if ($signoff == 0) {			ERROR("MISSING_SIGN_OFF",			      "Missing Signed-off-by: line(s)\n");		} elsif ($authorsignoff != 1) {			# authorsignoff values:			# 0 -> missing sign off			# 1 -> sign off identical			# 2 -> names and addresses match, comments mismatch			# 3 -> addresses match, names different			# 4 -> names match, addresses different			# 5 -> names match, addresses excluding subaddress details (refer RFC 5233) match 			my $sob_msg = "'From: $author' != 'Signed-off-by: $author_sob'"; 			if ($authorsignoff == 0) {				ERROR("NO_AUTHOR_SIGN_OFF",				      "Missing Signed-off-by: line by nominal patch author '$author'\n");			} elsif ($authorsignoff == 2) {				CHK("FROM_SIGN_OFF_MISMATCH",				    "From:/Signed-off-by: email comments mismatch: $sob_msg\n");			} elsif ($authorsignoff == 3) {				WARN("FROM_SIGN_OFF_MISMATCH",				     "From:/Signed-off-by: email name mismatch: $sob_msg\n");			} elsif ($authorsignoff == 4) {				WARN("FROM_SIGN_OFF_MISMATCH",

Lines 7001–7500 of 7586. Previous lines