public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug analyzer/95758] New: -Wanalyzer-use-after-free false positive when compiling glibc regex.c
@ 2020-06-19  5:56 eggert at cs dot ucla.edu
  2021-03-12 21:41 ` [Bug analyzer/95758] Various issues " dmalcolm at gcc dot gnu.org
  0 siblings, 1 reply; 2+ messages in thread
From: eggert at cs dot ucla.edu @ 2020-06-19  5:56 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95758

            Bug ID: 95758
           Summary: -Wanalyzer-use-after-free false positive when
                    compiling glibc regex.c
           Product: gcc
           Version: 10.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: analyzer
          Assignee: dmalcolm at gcc dot gnu.org
          Reporter: eggert at cs dot ucla.edu
  Target Milestone: ---

Created attachment 48755
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=48755&action=edit
compressed .i file illustrating the -Wanalyzer-use-after-free false positive

When using GCC 10.1.0 -fanalyzer to compile Glibc/Gnulib regex.c I found
several -fanalyzer false positives. Most seem to come from GCC bugs already
reported (Bug#93695, Bug#94458, Bug#94851) but one might be new. To reproduce
the problem on x86-64, uncompress the attached file t4b.i.gz and the compile
t4b.i with the command:

gcc -S -fanalyzer -Wno-analyzer-double-free -Wno-analyzer-malloc-leak
-Wno-analyzer-null-dereference t4b.i

This should be a clean compile, but the output is the following, which is a
false alarm:

t4b.i: In function 'free_charset':
t4b.i:11582:13: warning: use after 'free' of 'cset' [CWE-416]
[-Wanalyzer-use-after-free]
11582 |   free (cset->mbchars);
      |         ~~~~^~~~~~~~~
  'rpl_regfree': events 1-4
    |
    | 7610 | rpl_regfree (regex_t *preg)
    |      | ^~~~~~~~~~~
    |      | |
    |      | (1) entry to 'rpl_regfree'
    |......
    | 7613 |   if (__builtin_expect ((dfa !=
    |      |      ~
    |      |      |
    |      |      (2) following 'true' branch...
    |......
    | 7618 |       free_dfa_content (dfa);
    |      |       ~~~~~~~~~~~~~~~~~~~~~~
    |      |       |
    |      |       (3) ...to here
    |      |       (4) calling 'free_dfa_content' from 'rpl_regfree'
    |
    +--> 'free_dfa_content': events 5-10
           |
           | 7566 | free_dfa_content (re_dfa_t *dfa)
           |      | ^~~~~~~~~~~~~~~~
           |      | |
           |      | (5) entry to 'free_dfa_content'
           |......
           | 7569 |   if (dfa->nodes)
           |      |      ~
           |      |      |
           |      |      (6) following 'true' branch...
           | 7570 |     for (i = 0; i < dfa->nodes_len; ++i)
           |      |     ~~~  ~~~~~
           |      |     |      |
           |      |     |      (7) ...to here
           |      |     (8) following 'true' branch...
           | 7571 |       free_token (dfa->nodes + i);
           |      |       ~~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |       |              |
           |      |       |              (9) ...to here
           |      |       (10) calling 'free_token' from 'free_dfa_content'
           |
           +--> 'free_token': events 11-15
                  |
                  |11648 | free_token (re_token_t *node)
                  |      | ^~~~~~~~~~
                  |      | |
                  |      | (11) entry to 'free_token'
                  |11649 | {
                  |11650 |   if (node->type == COMPLEX_BRACKET &&
node->duplicated == 0)
                  |      |     
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |      |                              |               
   |
                  |      |      |                              |               
   (13) ...to here
                  |      |      |                              (14) following
'true' branch...
                  |      |      (12) following 'true' branch...
                  |11651 |     free_charset (node->opr.mbcset);
                  |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |     |
                  |      |     (15) ...to here
                  |
           <------+
           |
         'free_dfa_content': events 16-19
           |
           | 7570 |     for (i = 0; i < dfa->nodes_len; ++i)
           |      |     ~~~
           |      |     |
           |      |     (17) following 'true' branch...
           | 7571 |       free_token (dfa->nodes + i);
           |      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |       |              |
           |      |       |              (18) ...to here
           |      |       (16) returning to 'free_dfa_content' from
'free_token'
           |      |       (19) calling 'free_token' from 'free_dfa_content'
           |
           +--> 'free_token': events 20-24
                  |
                  |11648 | free_token (re_token_t *node)
                  |      | ^~~~~~~~~~
                  |      | |
                  |      | (20) entry to 'free_token'
                  |11649 | {
                  |11650 |   if (node->type == COMPLEX_BRACKET &&
node->duplicated == 0)
                  |      |     
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |      |                              |               
   |
                  |      |      |                              |               
   (22) ...to here
                  |      |      |                              (23) following
'true' branch...
                  |      |      (21) following 'true' branch...
                  |11651 |     free_charset (node->opr.mbcset);
                  |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |     |
                  |      |     (24) ...to here
                  |
           <------+
           |
         'free_dfa_content': events 25-28
           |
           | 7570 |     for (i = 0; i < dfa->nodes_len; ++i)
           |      |     ~~~
           |      |     |
           |      |     (26) following 'true' branch...
           | 7571 |       free_token (dfa->nodes + i);
           |      |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~
           |      |       |              |
           |      |       |              (27) ...to here
           |      |       (25) returning to 'free_dfa_content' from
'free_token'
           |      |       (28) calling 'free_token' from 'free_dfa_content'
           |
           +--> 'free_token': events 29-35
                  |
                  |11648 | free_token (re_token_t *node)
                  |      | ^~~~~~~~~~
                  |      | |
                  |      | (29) entry to 'free_token'
                  |11649 | {
                  |11650 |   if (node->type == COMPLEX_BRACKET &&
node->duplicated == 0)
                  |      |     
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |      |                              |               
   |
                  |      |      |                              |               
   (31) ...to here
                  |      |      |                              (32) following
'true' branch...
                  |      |      (30) following 'true' branch...
                  |11651 |     free_charset (node->opr.mbcset);
                  |      |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                  |      |     |
                  |      |     (33) ...to here
                  |      |     (34) freed here
                  |      |     (35) calling 'free_charset' from 'free_token'
                  |
                  +--> 'free_charset': events 36-37
                         |
                         |11580 | free_charset (re_charset_t *cset)
                         |      | ^~~~~~~~~~~~
                         |      | |
                         |      | (36) entry to 'free_charset'
                         |11581 | {
                         |11582 |   free (cset->mbchars);
                         |      |         ~~~~~~~~~~~~~
                         |      |             |
                         |      |             (37) use after 'free' of 'cset';
freed at (34)
                         |

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [Bug analyzer/95758] Various issues when compiling glibc regex.c
  2020-06-19  5:56 [Bug analyzer/95758] New: -Wanalyzer-use-after-free false positive when compiling glibc regex.c eggert at cs dot ucla.edu
@ 2021-03-12 21:41 ` dmalcolm at gcc dot gnu.org
  0 siblings, 0 replies; 2+ messages in thread
From: dmalcolm at gcc dot gnu.org @ 2021-03-12 21:41 UTC (permalink / raw)
  To: gcc-bugs

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95758

David Malcolm <dmalcolm at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Blocks|                            |99390
            Summary|-Wanalyzer-use-after-free   |Various issues when
                   |false positive when         |compiling glibc regex.c
                   |compiling glibc regex.c     |

--- Comment #1 from David Malcolm <dmalcolm at gcc dot gnu.org> ---
Thanks for filing this.

I tried again with GCC 11 HEAD and I don't see the use-after-free.  If there
are use-after-free bugs, the above looks likely to be another dup of bug 93695.

Adding -Wanalyzer-too-complex shows that the analyzer is hitting complexity
limits and giving up at numerous places in the code (it takes a *long* time on
the attachment) - which could be masking the use-after-free false positive.  It
looks like the call summarization logic is failing, leading to blog-up of the
analysis when all of the various nested function calls are expanded.

I also see many -Wanalyzer-malloc-leak reports, which may or may not be false
positives; difficult to tell without diving into the code.

Updating "Summary" accordingly, and adding to the call summarization tracker.


Referenced Bugs:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=99390
[Bug 99390] [meta-bug] tracker bug for call summaries in -fanalyzer

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2021-03-12 21:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-19  5:56 [Bug analyzer/95758] New: -Wanalyzer-use-after-free false positive when compiling glibc regex.c eggert at cs dot ucla.edu
2021-03-12 21:41 ` [Bug analyzer/95758] Various issues " dmalcolm at gcc dot gnu.org

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).