This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug sanitizer/69276] New: Address sanitizer does not handle heap overflow


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]