https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69276
Bug ID: 69276 Summary: Address sanitizer does not handle heap overflow Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: sanitizer Assignee: unassigned at gcc dot gnu.org Reporter: marxin at gcc dot gnu.org 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 Target Milestone: --- Created attachment 37341 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=37341&action=edit suggested patch Hi. Using master of the GCC repository, following test-case can't be spotted by address sanitizer: $ xclip missing-store.C #include <new> #include <stdlib.h> struct vec { int size; }; struct vnull { operator vec() { return vec(); } }; vnull vNULL; struct A { A(): value2 (vNULL) {} int value; vec value2; }; int main() { int *array = (int *)malloc (sizeof (int) * 1); A *a = new (array) A (); free (array); } $ g++ -fsanitize=address missing-store.C $ ./a.out && echo $? 0 However, valgrind can detect that: $ g++ missing-store.C $ valgrind ./a.out ==11323== Memcheck, a memory error detector ==11323== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==11323== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info ==11323== Command: ./a.out ==11323== ==11323== Invalid write of size 4 ==11323== at 0x4006EF: A::A() (in /home/marxin/Programming/testcases/asan-clobber/a.out) ==11323== by 0x40068D: main (in /home/marxin/Programming/testcases/asan-clobber/a.out) ==11323== Address 0x5a83c84 is 0 bytes after a block of size 4 alloc'd ==11323== at 0x4C2A00F: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==11323== by 0x400668: main (in /home/marxin/Programming/testcases/asan-clobber/a.out) Problem is that in asan.c we do not instrument stores that come from gimple_call statements. Using suggested (and untested) patch in attachment, the compiler can detect the problem: ./a.out ================================================================= ==19667==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000eff4 at pc 0x000000400a40 bp 0x7fffffffdd00 sp 0x7fffffffdcf8 WRITE of size 4 at 0x60200000eff4 thread T0 #0 0x400a3f in A::A() /home/marxin/Programming/testcases/asan-clobber/missing-store.C:17 #1 0x40097d in main /home/marxin/Programming/testcases/asan-clobber/missing-store.C:25 #2 0x7ffff621c60f in __libc_start_main (/lib64/libc.so.6+0x2060f) #3 0x400878 in _start (/home/marxin/Programming/testcases/asan-clobber/a.out+0x400878) 0x60200000eff4 is located 0 bytes to the right of 4-byte region [0x60200000eff0,0x60200000eff4) allocated by thread T0 here: #0 0x7ffff6f01c28 in __interceptor_malloc ../../../../libsanitizer/asan/asan_malloc_linux.cc:38 #1 0x400958 in main /home/marxin/Programming/testcases/asan-clobber/missing-store.C:24 #2 0x7ffff621c60f in __libc_start_main (/lib64/libc.so.6+0x2060f) SUMMARY: AddressSanitizer: heap-buffer-overflow /home/marxin/Programming/testcases/asan-clobber/missing-store.C:17 in A::A() Shadow bytes around the buggy address: 0x0c047fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa =>0x0c047fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa[04]fa 0x0c047fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c047fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Heap right redzone: fb Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack partial redzone: f4 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==19667==ABORTING Can please some from sanitizer folk provide a comment about suggested approach? Thanks, Martin