On 05/06/2016 01:48 PM, Yury Gribov wrote:
> On 05/06/2016 02:04 PM, Martin Liška wrote:
>> Hello.
>>
>> I've started working on the patch couple of month go, basically after
>> a brief discussion with Jakub on IRC.
>>
>> I'm sending the initial version which can successfully run instrumented
>> tramp3d, postgresql server and Inkscape. It catches the basic set of
>> examples which are added in following patch.
>>
>> The implementation is quite straightforward as works in following steps:
>>
>> 1) Every local variable stack slot is poisoned at the very beginning of a 
>> function (RTL emission)
>> 2) In gimplifier, once we spot a DECL_EXPR, a variable is unpoisoned (by 
>> emitting ASAN_MARK builtin)
>> and the variable is marked as addressable
>> 3) Similarly, BIND_EXPR is the place where we poison the variable (scope 
>> exit)
>> 4) At the very end of the function, we clean up the poisoned memory
>> 5) The builtins are expanded to call to libsanitizer run-time library 
>> (__asan_poison_stack_memory, __asan_unpoison_stack_memory)
> 
> Can we inline these?

Currently not as libasan is a shared library that an instrumented executable is 
linked with.
Possible solution would be to directly emit gimple instruction that would 
poison/unpoison the memory.
But it's not a trivial job which is done in the poisoning code (ALWAYS_INLINE 
void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, u8 value)

> 
>> 6) As the use-after-scope stuff is already included in libsanitizer, no 
>> change is needed for the library
> 
> Note that upstream seems to use a different cmdline interface. They don't 
> have a dedicated -fsanitize=use-after-scope and instead consider it to be a 
> part of -fsanitize=address (disabled by default, enabled via -mllvm 
> -asan-use-after-scope=1). I'd suggest to keep this interface (or at least 
> discuss with them) and use GCC's --param.
> 
> FTR here's the upstream work on this: http://reviews.llvm.org/D19347

Thanks for the link, I will adapt part of the test to our test-suite.
Some of them are really interesting.

Martin

> 
>> Example:
>>
>> int
>> main (void)
>> {
>>    char *ptr;
>>    {
>>      char my_char[9];
>>      ptr = &my_char[0];
>>    }
>>
>>    *(ptr+9) = 'c';
>> }
>>
>> ./a.out
>> =================================================================
>> ==12811==ERROR: AddressSanitizer: stack-use-after-scope on address 
>> 0x7ffec9bcff69 at pc 0x000000400a73 bp 0x7ffec9bcfef0 sp 0x7ffec9bcfee8
>> WRITE of size 1 at 0x7ffec9bcff69 thread T0
>>      #0 0x400a72 in main (/tmp/a.out+0x400a72)
>>      #1 0x7f100824860f in __libc_start_main (/lib64/libc.so.6+0x2060f)
>>      #2 0x400868 in _start (/tmp/a.out+0x400868)
>>
>> Address 0x7ffec9bcff69 is located in stack of thread T0 at offset 105 in 
>> frame
>>      #0 0x400945 in main (/tmp/a.out+0x400945)
>>
>>    This frame has 2 object(s):
>>      [32, 40) 'ptr'
>>      [96, 105) 'my_char' <== Memory access at offset 105 overflows this 
>> variable
>> HINT: this may be a false positive if your program uses some custom stack 
>> unwind mechanism or swapcontext
>>        (longjmp and C++ exceptions *are* supported)
>> SUMMARY: AddressSanitizer: stack-use-after-scope (/tmp/a.out+0x400a72) in 
>> main
>> Shadow bytes around the buggy address:
>>    0x100059371f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059371fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059371fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059371fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059371fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> =>0x100059371fe0: f1 f1 f1 f1 00 f4 f4 f4 f2 f2 f2 f2 f8[f8]f4 f4
>>    0x100059371ff0: f3 f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059372000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059372010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059372020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>    0x100059372030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> 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
>> ==12811==ABORTING
>>
>> As mentioned, it's request for comment as it still has couple of limitations:
>> a) VLA are not supported, which should make sense as we are unable to 
>> allocate a stack slot for that
> 
> Note that we plan some work on VLA sanitization later this year (upstream 
> ASan now sanitizes dynamic allocas and VLAs).
> 
>> b) we can possibly strip some instrumentation in situations where a variable 
>> is introduced in a very first BB (RTL poisoning is superfluous).
>> Similarly for a very last BB of a function, we can strip end of scope 
>> poisoning (and RTL unpoisoning). I'll do that incrementally.
>> c) We require -fstack-reuse=none option, maybe it worth to warn a user if 
>> -fsanitize=use-after-scope is provided without the option?
> 
> As a user, I'd prefer it to be automatically disabled when use-after-scope is 
> on (unless it has been set explicitly in cmdline in which case we should 
> probably issue error).
> 
>> d) An instrumented binary is quite slow (~20x for tramp3d) as every function 
>> call produces many memory read/writes. I'm wondering whether
>> we should provide a faster alternative (like instrument just variables that 
>> have address taken) ?
> 
> Can this due to -fstack-reuse or to outline poisoning? The latter sounds 
> particularly heavy.
> 
>> Patch can survive bootstrap and regression tests on x86_64-linux-gnu.
> 
> That's bootstrap-asan?
> 
>> Thanks for feedback.
>> Martin
>>
> 

Reply via email to