some pointer might be null
When I compile procps-ng using gcc 10.4.0 with compiler option -fanalyzer
enabled, it generated following :
‘process_sf_options’: events 1-4
|
| 752 | const char *process_sf_options(void){
| | ^~~~~~~~~~~~~~~~~~
| | |
| | (1) entry to ‘process_sf_options’
|......
| 755 | if(sf_list){
| | ~
| | |
| | (2) following ‘true’ branch...
| 756 | const char *err;
| | ~~~~~
| | |
| | (3) ...to here
| 757 | err = parse_O_option(sf_list);
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (4) calling ‘parse_O_option’ from ‘process_sf_options’
|
+--> ‘parse_O_option’: events 5-10
|
| 504 | static const char *parse_O_option(sf_node *sfn){
| | ^~~~~~~~~~~~~~
| | |
| | (5) entry to ‘parse_O_option’
|......
| 512 | switch(sfn->sf_code){
| | ~~~~~~
| | |
| | (6) following ‘case 3:’ branch...
|......
| 525 | case SF_B_O: /*** both ***/
| | ~~~~
| | |
| | (7) ...to here
|......
| 528 | if(!err){ /* success as sorting code */
| | ~
| | |
| | (8) following ‘true’ branch (when ‘err’ is NULL)...
| 529 | short_sort_parse(sfn);
| | ~~~~~~~~~~~~~~~~~~~~~
| | |
| | (9) ...to here
| | (10) calling ‘short_sort_parse’ from ‘parse_O_option’
|
+--> ‘short_sort_parse’: events 11-16
|
| 460 | static const char *short_sort_parse(sf_node *sfn){
| | ^~~~~~~~~~~~~~~~
| | |
| | (11) entry to ‘short_sort_parse’
|......
| 470 | switch(tmp){
| | ~~~~~~
| | |
| | (12) following ‘default:’ branch...
|......
| 480 | default:
| | ~~~~~~~
| | |
| | (13) ...to here
| 481 | ss = search_shortsort_array(tmp);
| 482 | if(!ss) return _("unknown sort specifier");
| | ~
| | |
| | (14) following ‘false’ branch (when ‘ss’ is non-NULL)...
| 483 | snode = do_one_sort_spec(ss->spec);
| | ~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (16) calling ‘do_one_sort_spec’ from ‘short_sort_parse’
| | (15) ...to here
|
+--> ‘do_one_sort_spec’: events 17-23
|
| 323 | static sort_node *do_one_sort_spec(const char *spec){
| | ^~~~~~~~~~~~~~~~
| | |
| | (17) entry to ‘do_one_sort_spec’
|......
| 326 | if(*spec == '-'){
| | ~
| | |
| | (18) following ‘true’ branch...
| 327 | reverse = 1;
| | ~~~~~~~
| | |
| | (19) ...to here
|......
| 333 | if(fs){
| | ~
| | |
| | (20) following ‘true’ branch (when ‘fs’ is non-NULL)...
| 334 | sort_node *thisnode;
| | ~~~~~~~~~
| | |
| | (21) ...to here
| | (22) this call could return NULL
| 335 | thisnode = malloc(sizeof(sort_node));
| 336 | thisnode->pr = fs->pr;
| | ~~~~~~~~~~~~~~~~~~~~~
| | |
| | (23) ‘thisnode’ could be NULL: unchecked value from (22)
|
ps/sortformat.c:565:11: warning: dereference of possibly-NULL ‘sfn’ [CWE-690] [-Wanalyzer-possible-null-dereference]
565 | sfn->sf = strdup(arg);
| ^
‘defer_sf_option’: event 1
|
| 558 | sf_node *sfn;
| | ^~~~~~~
| | |
| | (1) this call could return NULL
|
‘defer_sf_option’: event 2
|
| 565 | sfn->sf = strdup(arg);
| | ^
| | |
| | (2) ‘sfn’ could be NULL: unchecked value from (1)
|
pgrep.c:495:4: warning: use of possibly-NULL ‘re’ where non-null expected [CWE-690] [-Wanalyzer-possible-null-argument]
495 | sprintf (re, "^(%s)$", opt_pattern);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
‘main’: events 1-2
|
| 1005 | int main (int argc, char **argv)
| | ^~~~
| | |
| | (1) entry to ‘main’
|......
| 1026 | parse_opts (argc, argv);
| | ~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (2) calling ‘parse_opts’ from ‘main’
|
+--> ‘parse_opts’: events 3-7
|
| 752 | static void parse_opts (int argc, char **argv)
| | ^~~~~~~~~~
| | |
| | (3) entry to ‘parse_opts’
|......
| 977 | if(opt_pidfile){
| | ~
| | |
| | (4) following ‘false’ branch...
|......
| 985 | if (argc - optind == 1)
| | ~~ ~
| | | |
| | | (6) following ‘true’ branch...
| | (5) ...to here
| 986 | opt_pattern = argv[optind];
| | ~~~~~~~~~~~
| | |
| | (7) ...to here
|
<------+
|
‘main’: events 8-9
|
| 1026 | parse_opts (argc, argv);
| | ^~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (8) returning to ‘main’ from ‘parse_opts’
| 1027 |
| 1028 | procs = select_procs (&num);
| | ~~~~~~~~~~~~~~~~~~~
| | |
| | (9) calling ‘select_procs’ from ‘main’
|
+--> ‘select_procs’: events 10-11
|
| 533 | static struct el * select_procs (int *num)
| | ^~~~~~~~~~~~
| | |
| | (10) entry to ‘select_procs’
|......
| 546 | char *cmdline = xmalloc(cmdlen);
| | ~~~~~~~~~~~~~~~
| | |
| | (11) calling ‘xmalloc’ from ‘select_procs’
|
+--> ‘xmalloc’: events 12-14
|
|./include/xalloc.h:23:7:
| 23 | void *xmalloc(const size_t size)
| | ^~~~~~~
| | |
| | (12) entry to ‘xmalloc’
|......
| 26 | if (!ret && size)
| | ~
| | |
| | (13) following ‘false’ branch...
| 27 | xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
| 28 | return ret;
| | ~~~~~~
| | |
| | (14) ...to here
|
<------+
|
‘select_procs’: events 15-16
|
|pgrep.c:546:18:
| 546 | char *cmdline = xmalloc(cmdlen);
| | ^~~~~~~~~~~~~~~
| | |
| | (15) returning to ‘select_procs’ from ‘xmalloc’
| 547 | char *cmdsearch = xmalloc(cmdlen);
| | ~~~~~~~~~~~~~~~
| | |
| | (16) calling ‘xmalloc’ from ‘select_procs’
|
+--> ‘xmalloc’: events 17-19
|
|./include/xalloc.h:23:7:
| 23 | void *xmalloc(const size_t size)
| | ^~~~~~~
| | |
| | (17) entry to ‘xmalloc’
|......
| 26 | if (!ret && size)
| | ~
| | |
| | (18) following ‘false’ branch...
| 27 | xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
| 28 | return ret;
| | ~~~~~~
| | |
| | (19) ...to here
|
<------+
|
‘select_procs’: events 20-21
|
|pgrep.c:547:20:
| 547 | char *cmdsearch = xmalloc(cmdlen);
| | ^~~~~~~~~~~~~~~
| | |
| | (20) returning to ‘select_procs’ from ‘xmalloc’
| 548 | char *cmdoutput = xmalloc(cmdlen);
| | ~~~~~~~~~~~~~~~
| | |
| | (21) calling ‘xmalloc’ from ‘select_procs’
|
+--> ‘xmalloc’: events 22-24
|
|./include/xalloc.h:23:7:
| 23 | void *xmalloc(const size_t size)
| | ^~~~~~~
| | |
| | (22) entry to ‘xmalloc’
|......
| 26 | if (!ret && size)
| | ~
| | |
| | (23) following ‘false’ branch...
| 27 | xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
| 28 | return ret;
| | ~~~~~~
| | |
| | (24) ...to here
|
<------+
|
‘select_procs’: events 25-26
|
|pgrep.c:548:20:
| 548 | char *cmdoutput = xmalloc(cmdlen);
| | ^~~~~~~~~~~~~~~
| | |
| | (25) returning to ‘select_procs’ from ‘xmalloc’
|......
| 554 | ptp = do_openproc();
| | ~~~~~~~~~~~~~
| | |
| | (26) calling ‘do_openproc’ from ‘select_procs’
|
+--> ‘do_openproc’: events 27-31
|
| 453 | static PROCTAB *do_openproc (void)
| | ^~~~~~~~~~~
| | |
| | (27) entry to ‘do_openproc’
|......
| 462 | if (opt_oldest || opt_newest || opt_pgrp || opt_sid || opt_term || opt_older)
| | ~
| | |
| | (28) following ‘true’ branch...
| 463 | flags |= PROC_FILLSTAT;
| | ~~~~~
| | |
| | (29) ...to here
| 464 | if (!(flags & PROC_FILLSTAT))
| | ~
| | |
| | (30) following ‘false’ branch...
| 465 | flags |= PROC_FILLSTATUS; /* FIXME: need one, and PROC_FILLANY broken */
| 466 | if (opt_ns_pid)
| | ~~
| | |
| | (31) ...to here
|
<------+
|
‘select_procs’: events 32-33
|
| 554 | ptp = do_openproc();
| | ^~~~~~~~~~~~~
| | |
| | (32) returning to ‘select_procs’ from ‘do_openproc’
| 555 | preg = do_regcomp();
| | ~~~~~~~~~~~~
| | |
| | (33) calling ‘do_regcomp’ from ‘select_procs’
|
+--> ‘do_regcomp’: events 34-37
|
| 483 | static regex_t * do_regcomp (void)
| | ^~~~~~~~~~
| | |
| | (34) entry to ‘do_regcomp’
|......
| 487 | if (opt_pattern) {
| | ~
| | |
| | (35) following ‘true’ branch...
| 488 | char *re;
| | ~~~~
| | |
| | (36) ...to here
|......
| 492 | preg = xmalloc (sizeof (regex_t));
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (37) calling ‘xmalloc’ from ‘do_regcomp’
|
+--> ‘xmalloc’: events 38-40
|
|./include/xalloc.h:23:7:
| 23 | void *xmalloc(const size_t size)
| | ^~~~~~~
| | |
| | (38) entry to ‘xmalloc’
|......
| 26 | if (!ret && size)
| | ~
| | |
| | (39) following ‘false’ branch...
| 27 | xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
| 28 | return ret;
| | ~~~~~~
| | |
| | (40) ...to here
|
<------+
|
‘do_regcomp’: events 41-44
|
|pgrep.c:492:10:
| 492 | preg = xmalloc (sizeof (regex_t));
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (41) returning to ‘do_regcomp’ from ‘xmalloc’
| 493 | if (opt_exact) {
| | ~
| | |
| | (42) following ‘true’ branch...
| 494 | re = xmalloc (strlen (opt_pattern) + 5);
| | ~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | | |
| | | (44) calling ‘xmalloc’ from ‘do_regcomp’
| | (43) ...to here
|
+--> ‘xmalloc’: events 45-48
|
|./include/xalloc.h:23:7:
| 23 | void *xmalloc(const size_t size)
| | ^~~~~~~
| | |
| | (45) entry to ‘xmalloc’
|......
| 26 | if (!ret && size)
| | ~
| | |
| | (46) following ‘false’ branch...
| 27 | xerrx(XALLOC_EXIT_CODE, "cannot allocate %zu bytes", size);
| 28 | return ret;
| | ~~~~~~
| | |
| | (47) ...to here
| | (48) this call could return NULL
|
<------+
|
‘do_regcomp’: events 49-50
|
|pgrep.c:494:9:
| 494 | re = xmalloc (strlen (opt_pattern) + 5);
| | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (49) possible return of NULL to ‘do_regcomp’ from ‘xmalloc’
| 495 | sprintf (re, "^(%s)$", opt_pattern);
| | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| | |
| | (50) argument 1 (‘re’) from (48) could be NULL where non-null expected
|
I think this maybe a problem. Maybe we should add a pointer not null check before we use it?