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)
|
||
|
a deference was added 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 = ...".
|