An earlier commit attempted to cleanse our environment
of all useless trailing whitespace. But the effort did
not catch 'empty' lines with a single space before ^J.
This commit hopefully finishes off the earlier effort.
In the meantime, let's pray that contributors' editors
are configured so that such wasted crap is disallowed!
Reference(s):
commit fe75e26ab6
Signed-off-by: Jim Warner <james.warner@comcast.net>
		
	
		
			
				
	
	
		
			313 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			313 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
See http://www.freelists.org/post/procps/Scan-results,5
 | 
						|
 | 
						|
 | 
						|
	based on:
 | 
						|
filtered-with-patches.err
 | 
						|
 | 
						|
	these are the categories i've assigned:
 | 
						|
defect_was_fixed
 | 
						|
	EVALUATION_ORDER
 | 
						|
		pmap
 | 
						|
	TAINTED_STRING
 | 
						|
		tload
 | 
						|
 | 
						|
possibly_filter_out_?
 | 
						|
	MISSING_BREAK
 | 
						|
		slabtop
 | 
						|
		ps/output
 | 
						|
 | 
						|
avoidable_false_positive
 | 
						|
	DEADCODE
 | 
						|
		proc/readproc
 | 
						|
	FORWARD_NULL
 | 
						|
		top
 | 
						|
		vmstat
 | 
						|
	RESOURCE_LEAK
 | 
						|
		ps/parser (3)
 | 
						|
	STRING_NULL
 | 
						|
		pwdx
 | 
						|
		proc/readproc
 | 
						|
	TAINTED_SCALAR
 | 
						|
		pgrep
 | 
						|
		slabtop
 | 
						|
		top (3)
 | 
						|
	TAINTED_STRING
 | 
						|
		watch (2)
 | 
						|
	TOCTOU
 | 
						|
		sysctl (2)
 | 
						|
	UNINIT
 | 
						|
		ps/output (2)
 | 
						|
 | 
						|
unavoidable_false_positive_?
 | 
						|
	UNREACHABLE
 | 
						|
		ps/sortformat
 | 
						|
 | 
						|
unavoidable_false_positive_but_patched_anyway
 | 
						|
	OVERRUN_STATIC
 | 
						|
		top (no defect, but i yield)
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	pgrep ------------------------------------------------------------------------
 | 
						|
Error: TAINTED_SCALAR:
 | 
						|
	agree that argv might be tainted
 | 
						|
	but the (int)argv[1][1] index is being passed to isdigit() function (and glibc safely indexes into array sized at 384 bytes)
 | 
						|
	my_category: avoidable_false_positive (out of step with current glibc implementation)
 | 
						|
pgrep.c:720: tainted_data: Passing tainted variable "argv" to a tainted sink.
 | 
						|
pgrep.c:558: data_index: Using tainted variable "(int)argv[1][1]" as an index to pointer "*__ctype_b_loc()".
 | 
						|
 | 
						|
 | 
						|
	pmap -------------------------------------------------------------------------
 | 
						|
Error: EVALUATION_ORDER:
 | 
						|
	agree that there is a problem.
 | 
						|
	moreover, it deals with an undocumented command line argument (but sami has documentation addition pending)
 | 
						|
	the logic was altered in line with intent, hopefully avoids this warning
 | 
						|
	my_category: defect_was_fixed
 | 
						|
pmap.c:314: write_write_order: In "arg2 = (arg2 ? arg2++ : arg1)", "arg2" is written in "arg2" (the assignment left-hand side) and written in "arg2 ? arg2++ : arg1" but the order in which the side effects take place is undefined because there is no intervening sequence point.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	pwdx -------------------------------------------------------------------------
 | 
						|
Error: STRING_NULL:
 | 
						|
	static buffer is initialized to 0
 | 
						|
	it is +1 larger than size passed to readlink
 | 
						|
	was fixed in previous analysis
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
pwdx.c:86: string_null_argument: Function "readlink" does not terminate string "*buf".
 | 
						|
pwdx.c:73: var_assign_var: Assigning: "s" = "buf". Both now point to the same unterminated string.
 | 
						|
pwdx.c:73: var_assign_var: Assigning: "s" = "buf". Both now point to the same unterminated string.
 | 
						|
pwdx.c:73: var_assign_var: Assigning: "s" = "buf". Both now point to the same unterminated string.
 | 
						|
pwdx.c:92: string_null: Passing unterminated string "s" to "printf".
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	slabtop ----------------------------------------------------------------------
 | 
						|
Error: MISSING_BREAK:
 | 
						|
	intentional fall through after setting return code
 | 
						|
	no change made
 | 
						|
	my_category: possibly_filter_out_?
 | 
						|
slabtop.c:314: unterminated_case: This case (value 104) is not terminated by a 'break' statement.
 | 
						|
slabtop.c:316: fallthrough: The above case falls through to this one.
 | 
						|
 | 
						|
Error: TAINTED_SCALAR:
 | 
						|
	read limited to single byte signed 'char'
 | 
						|
	ultimately passed to toupper() function (and glibc safely indexes into array sized at 384 bytes)
 | 
						|
	my_category: avoidable_false_positive (out of step with current glibc implementation)
 | 
						|
slabtop.c:387: tainted_data_argument: Calling function "read" taints argument "c".
 | 
						|
slabtop.c:389: tainted_data: Passing tainted variable "c" to a tainted sink.
 | 
						|
slabtop.c:233: data_index: Using tainted variable "(int)c" as an index to pointer "*__ctype_toupper_loc()".
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	sysctl -----------------------------------------------------------------------
 | 
						|
Error: TOCTOU:
 | 
						|
	the pathlength between these two events cannot be reduced further
 | 
						|
	instead of assessing intervening lines of code, perhaps tool should assess 'if' statements (2)
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
sysctl.c:149: fs_check_call: Calling function "stat" to perform check on "tmpname".
 | 
						|
sysctl.c:168: toctou: Calling function "fopen" that uses "tmpname" after a check function. This can cause a time-of-check, time-of-use race condition.
 | 
						|
 | 
						|
Error: TOCTOU:
 | 
						|
	the pathlength between these two events cannot be reduced further
 | 
						|
	instead of assessing intervening lines of code, perhaps tool should assess 'if' statements (2)
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
sysctl.c:327: fs_check_call: Calling function "stat" to perform check on "tmpname".
 | 
						|
sysctl.c:345: toctou: Calling function "fopen" that uses "tmpname" after a check function. This can cause a time-of-check, time-of-use race condition.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	tload ------------------------------------------------------------------------
 | 
						|
Error: TAINTED_STRING:
 | 
						|
	altered perror call to provide an untainted string
 | 
						|
	my_category: defect_was_fixed
 | 
						|
tload.c:89: tainted_string: Passing tainted string "argv[optind]" to a function that cannot accept tainted data.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	top --------------------------------------------------------------------------
 | 
						|
Error: FORWARD_NULL:
 | 
						|
	cpus cannot be NULL without fp also being NULL
 | 
						|
	the very next 'if (!fp)' ensures cpus will be allocated
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
top.c:1790: assign_zero: Assigning: "cpus" = 0.
 | 
						|
top.c:1807: var_deref_op: Dereferencing null variable "cpus".
 | 
						|
 | 
						|
Error: OVERRUN_STATIC:
 | 
						|
	This "error" is centered around the following code:
 | 
						|
	      f = w->pflgsall[i + w->begpflg];
 | 
						|
	      w->procflgs[i] = f;
 | 
						|
	   #ifndef USE_X_COLHDR
 | 
						|
	      if (P_MAXPFLGS < f) continue;
 | 
						|
	   #endif
 | 
						|
	      h = Fieldstab[f].head;
 | 
						|
 | 
						|
	The enum P_MAXPFLGS is strictly a fencepost and can *never* appear in the arrays pflgsall or procflgs.
 | 
						|
	Thus it (39th element) cannot be used in referencing Fieldstab.
 | 
						|
	However, two enums of higher value (X_XON=40 and X_XOF=41) *can* appear in those arrays.
 | 
						|
	But the test against the fencepost ensures that those two enums are *never* used in referencing Fieldstab.
 | 
						|
 | 
						|
	When the analyzer sees the conditional using '<' and not '<=' it reports a false positive.
 | 
						|
 | 
						|
	i'm tired of explaining this so the program was changed to accommodate the tool's deficiency
 | 
						|
	my_category: unavoidable_false_positive_but_patched_anyway
 | 
						|
top.c:1417: overrun-local: Overrunning static array "Fieldstab", with 39 elements, at position 39 with index variable "f".
 | 
						|
 | 
						|
Error: TAINTED_SCALAR:
 | 
						|
	the index is used subordinate to a case statement ensuring a value between '1' and '4'
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
top.c:2442: tainted_data_argument: Calling function "chin" taints argument "ch".
 | 
						|
top.c:848: tainted_data_argument: Calling function "read" taints parameter "*buf".
 | 
						|
top.c:2452: tainted_data: Using tainted variable "ch - 49" as an index into an array "Winstk".
 | 
						|
 | 
						|
Error: TAINTED_SCALAR:
 | 
						|
	the index is used subordinate to as case statement ensuring a value between '1' and '4'
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
top.c:2719: tainted_data_argument: Calling function "chin" taints argument "ch".
 | 
						|
top.c:848: tainted_data_argument: Calling function "read" taints parameter "*buf".
 | 
						|
top.c:2720: tainted_data: Passing tainted variable "ch" to a tainted sink.
 | 
						|
top.c:2452: data_index: Using tainted variable "ch - 49" as an index to array "Winstk".
 | 
						|
 | 
						|
Error: TAINTED_SCALAR:
 | 
						|
	buf tainted by chin is zero terminated
 | 
						|
	single char is ultimately passed to isprintf() function (and glibc safely indexes into array sized at 384 bytes)
 | 
						|
	my_category: avoidable_false_positive (out of step with current glibc implementation)
 | 
						|
top.c:972: tainted_data_return: Function "keyin" returns tainted data.
 | 
						|
top.c:912: tainted_data_argument: Function "chin" taints argument "buf".
 | 
						|
top.c:848: tainted_data_argument: Calling function "read" taints parameter "*buf".
 | 
						|
top.c:926: return_tainted_data: Returning tainted variable "buf[0]".
 | 
						|
top.c:972: var_assign: Assigning: "key" = "keyin", which taints "key".
 | 
						|
top.c:1001: tainted_data: Using tainted variable "(int)key" as an index to pointer "*__ctype_b_loc()".
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	vmstat -----------------------------------------------------------------------
 | 
						|
Error: FORWARD_NULL:
 | 
						|
	partition made non-null with optarg for -p where statMode |= PARTITIONSTAT
 | 
						|
	if no optarg then program exits with usage
 | 
						|
	thus call to diskpartition_format will be with non-null pointer
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
vmstat.c:593: assign_zero: Assigning: "partition" = 0.
 | 
						|
vmstat.c:669: var_deref_model: Passing null variable "partition" to function "diskpartition_format", which dereferences it.
 | 
						|
vmstat.c:301: deref_parm_in_call: Function "strcmp" dereferences parameter "partition_name". (The dereference is assumed on the basis of the 'nonnull' parameter attribute.)
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	watch ------------------------------------------------------------------------
 | 
						|
Error: TAINTED_STRING:
 | 
						|
	even though the environment variable COLUMNS might begin tainted, from my analysis, the tool is totally mistaken
 | 
						|
	strtol actually untaints data in the form of 't' and 'endptr' then the environment variable COLUMNS is potentially purified with -1
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
watch.c:95: tainted_string_return_content: "getenv" returns tainted string content.
 | 
						|
watch.c:95: var_assign: Assigning: "s" = "getenv("COLUMNS")", which taints "s".
 | 
						|
watch.c:100: tainted_data_transitive: Call to function "strtol" with tainted argument "s" returns tainted data.
 | 
						|
watch.c:100: var_assign: Assigning: "t" = "strtol(s, &endptr, 0)", which taints "t".
 | 
						|
watch.c:101: var_assign_var: Assigning: "incoming_cols" = "(int)t". Both are now tainted.
 | 
						|
watch.c:102: var_assign_var: Assigning: "width" = "incoming_cols". Both are now tainted.
 | 
						|
watch.c:103: vararg_transitive: Call to "snprintf" with tainted argument "width" taints "env_col_buf".
 | 
						|
watch.c:104: tainted_string: Passing tainted string "env_col_buf" to a function that cannot accept tainted data.
 | 
						|
 | 
						|
Error: TAINTED_STRING:
 | 
						|
	even though the environment variable LINES might begin tainted, from my analysis, the tool is totally mistaken
 | 
						|
	strtol actually untaints data in the form of 't' and 'endptr' then the environment variable LINES is potentially purified with -1
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
watch.c:108: tainted_string_return_content: "getenv" returns tainted string content.
 | 
						|
watch.c:108: var_assign: Assigning: "s" = "getenv("LINES")", which taints "s".
 | 
						|
watch.c:113: tainted_data_transitive: Call to function "strtol" with tainted argument "s" returns tainted data.
 | 
						|
watch.c:113: var_assign: Assigning: "t" = "strtol(s, &endptr, 0)", which taints "t".
 | 
						|
watch.c:114: var_assign_var: Assigning: "incoming_rows" = "(int)t". Both are now tainted.
 | 
						|
watch.c:115: var_assign_var: Assigning: "height" = "incoming_rows". Both are now tainted.
 | 
						|
watch.c:116: vararg_transitive: Call to "snprintf" with tainted argument "height" taints "env_row_buf".
 | 
						|
watch.c:117: tainted_string: Passing tainted string "env_row_buf" to a function that cannot accept tainted data.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	proc/readproc ----------------------------------------------------------------
 | 
						|
Error: DEADCODE:
 | 
						|
	the tool does not understand gperf and the pseudo case labels preceded by goto
 | 
						|
	the following code snippets illustrate the deficiency:
 | 
						|
	   goto *(&&base + entry.offset);
 | 
						|
	      ...
 | 
						|
	   case_Threads:
 | 
						|
	     Threads = strtol(S,&S,10);
 | 
						|
	     continue;
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
proc/readproc.c:387: dead_error_condition: On this path, the condition "Threads" cannot be true.
 | 
						|
proc/readproc.c:115: const: After this line, the value of "Threads" is equal to 0.
 | 
						|
proc/readproc.c:115: assignment: Assigning: "Threads" = "0L".
 | 
						|
proc/readproc.c:388: dead_error_begin: Execution cannot reach this statement "P->nlwp = Threads;".
 | 
						|
 | 
						|
Error: STRING_NULL:
 | 
						|
	read is asked to retrieve -1 bytes than passed capacity:  num_read = read(fd, ret, cap - 1);
 | 
						|
	file2str does indeed null terminate sbuf:                 ret[num_read] = '\0';
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
proc/readproc.c:1193: string_null_argument: Function "file2str" does not terminate string "*sbuf".
 | 
						|
proc/readproc.c:514: string_null_argument: Function "read" fills array "*ret" with a non-terminated string.
 | 
						|
proc/readproc.c:1197: string_null: Passing unterminated string "sbuf" to a function expecting a null-terminated string.
 | 
						|
proc/readproc.c:447: string_null_sink_parm_call: Passing parameter "S" to "strchr" which expects a null-terminated string.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	ps/output --------------------------------------------------------------------
 | 
						|
Error: MISSING_BREAK:
 | 
						|
	intentional fall through
 | 
						|
	my_category: possibly_filter_out_?
 | 
						|
ps/output.c:1983: unterminated_default: The default case is not terminated by a 'break' statement.
 | 
						|
ps/output.c:1984: fallthrough: The above case falls through to this one.
 | 
						|
 | 
						|
Error: UNINIT:
 | 
						|
	the first member is initialized in the very next statement, sufficient for bsearch callback
 | 
						|
	   key.spec = findme;
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
ps/output.c:1737: var_decl: Declaring variable "key" without initializer.
 | 
						|
ps/output.c:1739: uninit_use_in_call: Using uninitialized value "key": field "key".flags is uninitialized when calling "bsearch".
 | 
						|
 | 
						|
Error: UNINIT:
 | 
						|
	the first member is initialized in the very next statement, sufficient for bsearch callback
 | 
						|
	   key.spec = findme;
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
ps/output.c:1745: var_decl: Declaring variable "key" without initializer.
 | 
						|
ps/output.c:1747: uninit_use_in_call: Using uninitialized value "key": field "key".head is uninitialized when calling "bsearch".
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	ps/parser --------------------------------------------------------------------
 | 
						|
Error: RESOURCE_LEAK:
 | 
						|
	intentional omission
 | 
						|
	abexit shortly
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
ps/parser.c:1021: alloc_fn: Calling allocation function "malloc".
 | 
						|
ps/parser.c:1021: var_assign: Assigning: "pidnode" =  storage returned from "malloc(sizeof (selection_node) /*24*/)".
 | 
						|
ps/parser.c:1041: leaked_storage: Variable "pidnode" going out of scope leaks the storage it points to.
 | 
						|
ps/parser.c:1062: leaked_storage: Variable "pidnode" going out of scope leaks the storage it points to.
 | 
						|
 | 
						|
Error: RESOURCE_LEAK:
 | 
						|
	intentional omission
 | 
						|
	abexit shortly
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
ps/parser.c:1025: alloc_fn: Calling allocation function "malloc".
 | 
						|
ps/parser.c:1025: var_assign: Assigning: "grpnode" =  storage returned from "malloc(sizeof (selection_node) /*24*/)".
 | 
						|
ps/parser.c:1041: leaked_storage: Variable "grpnode" going out of scope leaks the storage it points to.
 | 
						|
ps/parser.c:1062: leaked_storage: Variable "grpnode" going out of scope leaks the storage it points to.
 | 
						|
 | 
						|
Error: RESOURCE_LEAK:
 | 
						|
	intentional omission
 | 
						|
	abexit shortly
 | 
						|
	my_category: avoidable_false_positive
 | 
						|
ps/parser.c:1029: alloc_fn: Calling allocation function "malloc".
 | 
						|
ps/parser.c:1029: var_assign: Assigning: "sidnode" =  storage returned from "malloc(sizeof (selection_node) /*24*/)".
 | 
						|
ps/parser.c:1041: leaked_storage: Variable "sidnode" going out of scope leaks the storage it points to.
 | 
						|
ps/parser.c:1062: leaked_storage: Variable "sidnode" going out of scope leaks the storage it points to.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
	ps/sortformat ----------------------------------------------------------------
 | 
						|
Error: UNREACHABLE:
 | 
						|
	the tool does not understand the following 'label' usage (nor do i - perhaps some obscure compiler/platform warning/quirk)
 | 
						|
	   goto unknown;
 | 
						|
	      ...
 | 
						|
	   if(0) unknown:  err=errbuf;
 | 
						|
	my_category: unavoidable_false_positive_?
 | 
						|
ps/sortformat.c:312: unreachable: This code cannot be reached: "if (0){
 | 
						|
  unknown:
 | 
						|
  err = ...".
 |