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

            Bug ID: 92153
           Summary: [10 Regression] ICE / segmentation fault,
                    use-after-free at gcc/ggc-page.c:1159
           Product: gcc
           Version: 10.0
            Status: UNCONFIRMED
          Keywords: GC
          Severity: normal
          Priority: P3
         Component: middle-end
          Assignee: unassigned at gcc dot gnu.org
          Reporter: p...@gcc-bugzilla.mail.kapsi.fi
  Target Milestone: ---
              Host: i686-w64-mingw32 x86_64-w64-mingw32
            Target: aarch64-none-elf

Hi.

I suspect that the previous ggc-page commit [1] accidentally created an
use-after-free, which will be triggered at least on *-w64-mingw32 hosts.  On my
systems this is super easy to reproduce when using C++ frontend, C frontend
requires orders of magnitude larger input files.  I tried disabling any
security measures (such as ASLR) and tried this on multiple Windows 10 1903
machines.

(The input is not important here, just that release_pages() is called.)

$ cat ggc-pagecrash.cpp
#include <memory>

$ g++ -O0 ggc-pagecrash.cpp -wrapper gdb,--args
Thread 1 received signal SIGSEGV, Segmentation fault.
release_pages () at <trunk>/gcc/gcc/ggc-page.c:1159
(gdb) bt
#0  release_pages () at <trunk>/gcc/gcc/ggc-page.c:1159
#1  release_pages () at <trunk>/gcc/gcc/ggc-page.c:1016
#2  0x000000000069f113 in ggc_collect () at <trunk>/gcc/gcc/ggc-page.c:2205

(The rest of the stack frames omitted.)


gcc/ggc-page.c:
1158         free (g->allocation);
1159         n1 += g->alloc_size; // <-- this line was added


I'm not claiming that I would fully understand the page allocation code, but I
presume `g->allocation' does reference itself to some extent.  At least this is
what I'm seeing on one of my systems:

 862       allocation = XNEWVEC (char, alloc_size);
    // allocation=0x1e49b040, alloc_size=2101247,
...
 893       group->allocation = allocation;
    // group=0x1e49bfe0,

and, indeed, later on:

1158         free (g->allocation);
    // allocation=0x1e49b040,
1159         n1 += g->alloc_size;
    // g=0x1e49bfe0 -> SIGSEGV.


[1]
https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=474507cc277c500e580003f45ed91130adc0bde3

Reply via email to