On Thu, Jan 14, 2016 at 12:17 PM, Yuri Gribov <[email protected]> wrote:
> Hi Martin, > > On Thu, Jan 14, 2016 at 3:17 PM, Martin Liška <[email protected]> > wrote: > > Hello. > > > > Let me firstly give you big compliment for address sanitizer > infrastructure! > > I've been currently working as GCC developer and I find two potential > > interesting use-cases for the sanitizer: > > > > 1) use of uninitialized memory > > > > GCC started to annotate all class ctors and dtors with memory clobber > store: > > -flifetime-store > > > https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Optimize-Options.html#Optimize-Options > > > > Looks Firefox suffers from many of these errors and segfaults during > startup > > with latest GCC and link-time optimization. > > Let's assume following example: > > > > #include <stdio.h> > > #include <stdlib.h> > > #include <string.h> > > #include <new> > > > > struct A > > { > > char i[100]; > > A() {} > > ~A() {} > > }; > > > > int get_value (int *a, int i) > > { > > return a[i]; > > } > > > > int main() > > { > > int *ar = (int *)malloc (111); > > *ar = 123; > > fprintf (stderr, "memory: %p\n", ar); > > > > A* ap = new(ar) A; > > ap->~A(); > > > > get_value (ar, 10); // use of uninitialized memory > > > > return 0; > > } > > > > As you can see, calling get_value is an invalid operation. However, e.g. > > valgrind tool is unable to catch these as the value is initialized. > > I came with an experimental patch to address sanitizer that annotates > every > > memory clobber to call memory poisoning. On the other hand, > > every memory store must unpoison the memory. > > This has been brought up before in > https://github.com/google/sanitizers/issues/73 but guys decided to > firstly do this in MSan. I guess adding this to ASan as an option > would be cool because it's much easier to integrate (I'm not an owner > or maintainer though so speaking for myself here). > Correct. In msan this feature is already implemented: http://clang.llvm.org/docs/MemorySanitizer.html#use-after-destruction-detection I frankly don't know how to correctly implement it in asan because asan's shadow does not distinguish between reads and writes. > > > Sample output from patched GCC & sanitizer: > > > > ==12358==ERROR: AddressSanitizer: heap-clobbered-memory-read on address > > 0x60b00000afb8 at pc 0x000000400ad1 bp 0x7fffffffdca0 sp 0x7fffffffdc98 > > READ of size 4 at 0x60b00000afb8 thread T0 > > #0 0x400ad0 in get_value(int*, int) (/tmp/a.out+0x400ad0) > > #1 0x400bca in main (/tmp/a.out+0x400bca) > > #2 0x7ffff621960f in __libc_start_main (/lib64/libc.so.6+0x2060f) > > #3 0x4009a8 in _start (/tmp/a.out+0x4009a8) > > > > 0x60b00000afb8 is located 40 bytes inside of 111-byte region > > [0x60b00000af90,0x60b00000afff) > > allocated by thread T0 here: > > #0 0x7ffff6f02128 in __interceptor_malloc > > ../../../../libsanitizer/asan/asan_malloc_linux.cc:38 > > #1 0x400ae9 in main (/tmp/a.out+0x400ae9) > > #2 0x7ffff621960f in __libc_start_main (/lib64/libc.so.6+0x2060f) > > > > SUMMARY: AddressSanitizer: heap-clobbered-memory-read > (/tmp/a.out+0x400ad0) > > in get_value(int*, int) > > Shadow bytes around the buggy address: > > 0x0c167fff95a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff95b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff95c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff95d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff95e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > =>0x0c167fff95f0: fa fa f0 f0 f0 f0 f0[f0]f0 f0 f0 f0 f0 f0 00 07 > > 0x0c167fff9600: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff9610: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff9620: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff9630: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa > > 0x0c167fff9640: 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 > > Heap clobbered memory f0 > > > > Well, the implementation currently has granularity equal to 8 bytes and > > every clobber/store must be considered conservatively. Ideally, I would > like > > to be able to clobber (mark store) > > of every byte. Another issues is that I am unable to clear clobber shadow > > byte for stack memory after a frame is unwinded, not sure where to find a > > place where stacks are prepared? > > Current implementation only unpoisons stack redzones on exit from > function (see calls to asan_clear_shadow in > asan_emit_stack_protection). You'll probably have to change this to > unpoison the entire frame (if it contains C++ objects with non-trivial > dtors). > > > 2) memory access checks based on TBAA > > > > Every memory access in compiler is connected to an alias set and these > sets > > can be compared in runtime if the access is valid. > alias-sanitizer... yes, we thought about this before, but never implemented. This will probably be a different tool... > > Such check would require to assign 4B information (alias set number) for > > every byte (I know huge memory footprint), but it can provide interesting > > informations. > > Sounds very interesting. Wouldn't it be possible to round objects to 8 > bytes (same way as ASan does) to decrease the overhead? BTW note that > you'll have to take care of generating unique alias set numbers across > all compilation units which may not be easy (unless you plan to use > LTO). > > > Well, as I've briefly described my use-cases, I have couple of questions: > > a) Are these optimizations interesting enough to be eventually merged as > > part of sanitizer? > > b) I see need to create a separate shadow regions for different usages, > > maybe current shadow memory implementation can be generalized? > > You mean you'd want to have multiple distinct shadow areas for > different checks? I think the strategy until now was to have dedicated > tools (each with it's own shadow if at all) which you apply > separately. > Correct. Mixing several tools in one process is painful. (We do mix asan and ubsan, but that's because ubsan is simple). > > > Thank you for any suggestions, ides. > > Martin > > > > -- > > You received this message because you are subscribed to the Google Groups > > "address-sanitizer" group. > > To unsubscribe from this group and stop receiving emails from it, send an > > email to [email protected]. > > For more options, visit https://groups.google.com/d/optout. > > -- > You received this message because you are subscribed to the Google Groups > "address-sanitizer" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected]. > For more options, visit https://groups.google.com/d/optout. > -- You received this message because you are subscribed to the Google Groups "address-sanitizer" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. For more options, visit https://groups.google.com/d/optout.
