public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug sanitizer/101380] New: Segmentation fault in __asan_init
@ 2021-07-08 15:07 puspmvqyfzxrbytwsu at niwghx dot com
  2021-07-09  7:12 ` [Bug sanitizer/101380] " rguenth at gcc dot gnu.org
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: puspmvqyfzxrbytwsu at niwghx dot com @ 2021-07-08 15:07 UTC (permalink / raw)
  To: gcc-bugs

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

            Bug ID: 101380
           Summary: Segmentation fault in __asan_init
           Product: gcc
           Version: 11.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: puspmvqyfzxrbytwsu at niwghx dot com
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at gcc dot gnu.org
  Target Milestone: ---

/* ======== testcase.c ======== */
int main()
{
}
/* ======== end of source ======== */

When compiling with the command line
    gcc -no-pie -fsanitize=address testcase.c
the output file a.out contains a bug causing it to sometimes crash on startup
(pre-main) with a segmentation fault. This segmentation fault is not handled by
the address sanitizer, but gives the default segmentation fault
message.
According to my testing with ltrace, the segmentation fault seems to be caused
in __asan_init:

/* ======== ltrace ./a.out ======== */
__asan_init(1, 0x72a9c5ef89c8, 0x72a9c5ef89d8, 0x61d7e2856060 <no return ...>
--- SIGSEGV (Segmentation fault) ---
--- SIGSEGV (Segmentation fault) ---
+++ killed by SIGSEGV +++
/* ======== end of ltrace ======== */


/* ======== gcc -v -no-pie -fsanitize=address testcase.c ======== */
Es werden eingebaute Spezifikationen verwendet.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/lto-wrapper
Ziel: x86_64-pc-linux-gnu
Konfiguriert mit: /build/gcc/src/gcc/configure --prefix=/usr --libdir=/usr/lib
--libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info
--with-bugurl=https://bugs.archlinux.org/
--enable-languages=c,c++,ada,fortran,go,lto,objc,obj-c++,d --with-isl
--with-linker-hash-style=gnu --with-system-zlib --enable-__cxa_atexit
--enable-cet=auto --enable-checking=release --enable-clocale=gnu
--enable-default-pie --enable-default-ssp --enable-gnu-indirect-function
--enable-gnu-unique-object --enable-install-libiberty --enable-linker-build-id
--enable-lto --enable-multilib --enable-plugin --enable-shared
--enable-threads=posix --disable-libssp --disable-libstdcxx-pch
--disable-libunwind-exceptions --disable-werror
gdc_include_dir=/usr/include/dlang/gdc
Thread-Modell: posix
Unterstützte LTO-Kompressionsalgorithmen: zlib zstd
gcc-Version 11.1.0 (GCC)
COLLECT_GCC_OPTIONS='-v' '-no-pie' '-fsanitize=address' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/cc1 -quiet -v testcase.c -quiet
-dumpdir a- -dumpbase testcase.c -dumpbase-ext .c -mtune=generic -march=x86-64
-version -fsanitize=address -o /tmp/ccUMl4NV.s
GNU C17 (GCC) Version 11.1.0 (x86_64-pc-linux-gnu)
    kompiliert von GNU-C-Version 11.1.0, GMP Version 6.2.1, MPFR Version 4.1.0,
MPC Version 1.2.1. isl Versiom isl-0.24-GMP

GGC-Heuristik: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
nicht vorhandenes Verzeichnis
»/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../x86_64-pc-linux-gnu/include«
wird ignoriert
Suche für »#include "..."« beginnt hier:
Suche für »#include <...>« beginnt hier:
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include
 /usr/local/include
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include-fixed
 /usr/include
Ende der Suchliste.
GNU C17 (GCC) Version 11.1.0 (x86_64-pc-linux-gnu)
    kompiliert von GNU-C-Version 11.1.0, GMP Version 6.2.1, MPFR Version 4.1.0,
MPC Version 1.2.1. isl Versiom isl-0.24-GMP

GGC-Heuristik: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 3d0ac5c030c008e73f10e8b66957dbfa
COLLECT_GCC_OPTIONS='-v' '-no-pie' '-fsanitize=address' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a-'
 as -v --64 -o /tmp/ccPP003Z.o /tmp/ccUMl4NV.s
GNU assembler version 2.36.1 (x86_64-pc-linux-gnu) using BFD version (GNU
Binutils) 2.36.1
COMPILER_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/:/lib/../lib/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-no-pie' '-fsanitize=address' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a.'
 /usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/collect2 -plugin
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/liblto_plugin.so
-plugin-opt=/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/lto-wrapper
-plugin-opt=-fresolution=/tmp/ccy5uDZk.res -plugin-opt=-pass-through=-lgcc
-plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc
-plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id
--eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker
/lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crt1.o
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/crtbegin.o
-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0
-L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib -L/lib/../lib
-L/usr/lib/../lib -L/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../..
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/libasan_preinit.o
-lasan /tmp/ccPP003Z.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc
-lgcc --push-state --as-needed -lgcc_s --pop-state
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/crtend.o
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/../../../../lib/crtn.o
COLLECT_GCC_OPTIONS='-v' '-no-pie' '-fsanitize=address' '-mtune=generic'
'-march=x86-64' '-dumpdir' 'a.'
/* ======== end of output ======== */

Further information:
I am running this on an ArchLinux system with kernel
5.12.14-hardened1-1-hardened.
The used version of the address sanitizer library is 6.0.0:
/* ======== ldd a.out ======== */
        linux-vdso.so.1 (0x000065a50ebf3000)
        libasan.so.6 => /usr/lib/libasan.so.6 (0x000065a50e1f7000)
        libc.so.6 => /usr/lib/libc.so.6 (0x000065a50e02b000)
        libdl.so.2 => /usr/lib/../lib/libdl.so.2 (0x000065a50e024000)
        librt.so.1 => /usr/lib/../lib/librt.so.1 (0x000065a50e019000)
        libpthread.so.0 => /usr/lib/../lib/libpthread.so.0 (0x000065a50dff8000)
        libstdc++.so.6 => /usr/lib/../lib/libstdc++.so.6 (0x000065a50dde2000)
        libm.so.6 => /usr/lib/../lib/libm.so.6 (0x000065a50dc9c000)
        libgcc_s.so.1 => /usr/lib/../lib/libgcc_s.so.1 (0x000065a50dc81000)
        /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2
(0x000065a50ebf5000)
/* ======== end ======== */
/usr/lib/libasan.so.6 is a symbolic link to libasan.so.6.0.0

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

* [Bug sanitizer/101380] Segmentation fault in __asan_init
  2021-07-08 15:07 [Bug sanitizer/101380] New: Segmentation fault in __asan_init puspmvqyfzxrbytwsu at niwghx dot com
@ 2021-07-09  7:12 ` rguenth at gcc dot gnu.org
  2021-07-16 11:42 ` [Bug sanitizer/101380] Segmentation fault in address sanitizer initialization, caused by mmap-ing into the running code puspmvqyfzxrbytwsu at niwghx dot com
  2021-09-13 13:30 ` puspmvqyfzxrbytwsu at niwghx dot com
  2 siblings, 0 replies; 4+ messages in thread
From: rguenth at gcc dot gnu.org @ 2021-07-09  7:12 UTC (permalink / raw)
  To: gcc-bugs

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

Richard Biener <rguenth at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |WAITING
   Last reconfirmed|                            |2021-07-09
     Ever confirmed|0                           |1

--- Comment #1 from Richard Biener <rguenth at gcc dot gnu.org> ---
It works for me (openSUSE Leap 15.3) using self-built GCC 11.  I wonder if you
can share more details on the crash by running inside gdb providing a backtrace
and disassembly around the crash.

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

* [Bug sanitizer/101380] Segmentation fault in address sanitizer initialization, caused by mmap-ing into the running code
  2021-07-08 15:07 [Bug sanitizer/101380] New: Segmentation fault in __asan_init puspmvqyfzxrbytwsu at niwghx dot com
  2021-07-09  7:12 ` [Bug sanitizer/101380] " rguenth at gcc dot gnu.org
@ 2021-07-16 11:42 ` puspmvqyfzxrbytwsu at niwghx dot com
  2021-09-13 13:30 ` puspmvqyfzxrbytwsu at niwghx dot com
  2 siblings, 0 replies; 4+ messages in thread
From: puspmvqyfzxrbytwsu at niwghx dot com @ 2021-07-16 11:42 UTC (permalink / raw)
  To: gcc-bugs

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

puspmvqyfzxrbytwsu at niwghx dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Segmentation fault in       |Segmentation fault in
                   |__asan_init                 |address sanitizer
                   |                            |initialization, caused by
                   |                            |mmap-ing into the running
                   |                            |code

--- Comment #2 from puspmvqyfzxrbytwsu at niwghx dot com ---
The crash seems to only occur with ASLR enabled. When disabling ASLR via
setarch or gdb, I could not reproduce the issue.

I was not able to get a useful stack trace using gdb (when looking at the
segmentation fault, the stack trace printed by gdb looked like corrupted data,
with only a single stack frame printed).

So, I did some debugging with ptrace to get a stack trace before the program
crashes. From this, it looks like the allocator initialization code of the
address sanitizer library causes the crash by performing an mmap-syscall,
mapping something into the address range of the code which is being executed:

system call 9 is mmap
-> argument 0, here 0x0000600000000000, is the starting address (in the process
address space)
-> argument 1, here 0x0000040000000000, is the length to be mapped
=> The address range from 0x0000600000000000 to 0x0000640000000000 will be
mapped.
-> The instruction pointer, here 0x000063C62D125104, is within this address
range.


/* ==== system call entry information (acquired with ptrace) ==== */
  entering system call 0x09:
    argument 0: 0x0000600000000000
    argument 1: 0x0000040000003000
    argument 2: 0x0000000000000000
    argument 3: 0x0000000000004032
    argument 4: 0xFFFFFFFFFFFFFFFF
    argument 5: 0x0000000000000000
/* ==== stack trace (acquired with libunwind-ptrace) ==== */
[RIP: 0x000063C62D125104, RSP: 0x000079E7984D2D50]
_ZN11__sanitizer13internal_mmapEPvmiiiy+0x8
[RIP: 0x000063C62D129430, RSP: 0x000079E7984D2D70]
_ZN11__sanitizer9MmapNamedEPvmiiPKc+0x8
[RIP: 0x000063C62D12A049, RSP: 0x000079E7984D2DA0]
_ZN11__sanitizer20ReservedAddressRange4InitEmPKcm+0x8
[RIP: 0x000063C62D07931B, RSP: 0x000079E7984D2DC0]
_ZN6__asan19InitializeAllocatorERKNS_16AllocatorOptionsE+0xA7
[RIP: 0x000063C62D1174DF, RSP: 0x000079E7984D2DF0]
_ZN6__asanL16AsanInitInternalEv.part.0+0xA7
[RIP: 0x000063C62DA63F6E, RSP: 0x000079E7984D2E40] _dl_init+0x1
/* ================ */

Upon exit from the system call, I got the following information from ptrace
(indicating success of mmap):
  system call exiting: return value: 0x0000600000000000, is error: 0
At this point, I could no longer obtain a useful stack trace via
libunwind-ptrace. (Only a single stack-frame, not able to get a procedure name
corresponding to it, similar to what I got with gdb).
Then the segmentation fault occurs.

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

* [Bug sanitizer/101380] Segmentation fault in address sanitizer initialization, caused by mmap-ing into the running code
  2021-07-08 15:07 [Bug sanitizer/101380] New: Segmentation fault in __asan_init puspmvqyfzxrbytwsu at niwghx dot com
  2021-07-09  7:12 ` [Bug sanitizer/101380] " rguenth at gcc dot gnu.org
  2021-07-16 11:42 ` [Bug sanitizer/101380] Segmentation fault in address sanitizer initialization, caused by mmap-ing into the running code puspmvqyfzxrbytwsu at niwghx dot com
@ 2021-09-13 13:30 ` puspmvqyfzxrbytwsu at niwghx dot com
  2 siblings, 0 replies; 4+ messages in thread
From: puspmvqyfzxrbytwsu at niwghx dot com @ 2021-09-13 13:30 UTC (permalink / raw)
  To: gcc-bugs

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

--- Comment #3 from puspmvqyfzxrbytwsu at niwghx dot com ---
Summary of the problem, as far as I understand it now:

The address sanitizer initialisation code invokes the mmap-syscall (syscall
0x9) with the following paramaters:

0x0000600000000000 - the start address of the mapped memory range (MAP_FIXED is
set!)
0x0000040000003000 - length of the mapped memory range
0x0000000000000000 - protection: PROT_NONE: page may not be accessed
0x0000000000004032 - flags: MAP_NORESERVE | MAP_ANONYMOUS | MAP_FIXED |
MAP_PRIVATE
0xFFFFFFFFFFFFFFFF - file descriptor: -1
0x0000000000000000 - offset: 0

So it creates an anonymous mapping in the address range
from 0x0000600000000000 to 0x0000640000003000 (presumably to reserve memory for
the allocator), thereby also discarding any existing mappings into that memory
range (due to MAP_FIXED).

According to my testing, this syscall is always made with the same parameters
from the same call site (and always succeeds) in the above example program
compiled with:
        gcc -no-pie -fsanitize=address testcase.c

If that memory range happens to overlap with the running code (due to ASLR),
the program crashes immediately upon return from the syscall due to the
resulting address space corrpution.


Here is the stack trace of the call:
==== stack trace ====
procedure name                                           offset within
procedure (in bytes)
_ZN11__sanitizer13internal_mmapEPvmiiiy                  +0x8
_ZN11__sanitizer9MmapNamedEPvmiiPKc                      +0x0
_ZN11__sanitizer20ReservedAddressRange4InitEmPKcm        +0x60
_ZN6__asan19InitializeAllocatorERKNS_16AllocatorOptionsE 
_ZN6__asanL16AsanInitInternalEv.part.0                   
_dl_init                                                 
==== end of stack trace ====


Maybe the flag MAP_FIXED_NOREPLACE should be used here instead of MAP_FIXED?
That would prevent the syscall from corrupting the address space.
I don't know the implementation, so I don't know why MAP_FIXED is used here in
the first place.

Do you need any additional information for further debugging / fixing this bug?

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

end of thread, other threads:[~2021-09-13 13:30 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-08 15:07 [Bug sanitizer/101380] New: Segmentation fault in __asan_init puspmvqyfzxrbytwsu at niwghx dot com
2021-07-09  7:12 ` [Bug sanitizer/101380] " rguenth at gcc dot gnu.org
2021-07-16 11:42 ` [Bug sanitizer/101380] Segmentation fault in address sanitizer initialization, caused by mmap-ing into the running code puspmvqyfzxrbytwsu at niwghx dot com
2021-09-13 13:30 ` puspmvqyfzxrbytwsu at niwghx dot com

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).