On 01/26/2017 02:19 PM, Jakub Jelinek wrote:
> On Thu, Jan 26, 2017 at 02:04:00PM +0100, Martin Liška wrote:
>> + The option is enabled with <code>-fsanitize=address</code> and disabled
>
> s/enabled/& by default/
> s/disabled/& by default/
>
>> + with <code>-fsanitize=kernel-address</code>.
>> + Compared to the LLVM compiler, where the option already exists,
>> + the implementation in the GCC compiler has couple of improvements and
>> advantages:
>> + <ul>
>> + <li>A complex usage of gotos and case labels are properly handled and
>> should not
>> + report any false positive or false negatives.
>> + </li>
>> + <li>Shadow memory poisoning (and unpoisoning) is optimized out in
>> common situations
>> + where the call is not needed.
>> + </li>
>> + <li>C++ temporaries are sanitized.</li>
>> + <li>Sanitization can handle invalid memory stores that are optimized
>> out
>> + by the LLVM compiler when using an optimization level.</li>
>
> Have you verified it is true on the LLVM side (i.e. that they mishandle
> gotos or case labels, that they don't optimize away memory
> poisoning/unpoisoning in cases where gcc does, that they don't sanitize C++
> temporaries and that for optimized out invalid memory stores they don't
> sanitize them?
>
> Jakub
>
Yes:
1) gotos and switch:
with
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-3.c:
$ clang -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-3.c
-fsanitize=address -g && ./a.out
=================================================================
==14035==ERROR: AddressSanitizer: stack-use-after-scope on address
0x7ffefb11af20 at pc 0x0000004e73b0 bp 0x7ffefb11aef0 sp 0x7ffefb11aee8
WRITE of size 4 at 0x7ffefb11af20 thread T0
#0 0x4e73af in main
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-3.c:20:13
#1 0x7f34dea62290 in __libc_start_main
/usr/src/debug/glibc-2.24/csu/../csu/libc-start.c:289
#2 0x41b7d9 in _start
/home/abuild/rpmbuild/BUILD/glibc-2.24/csu/../sysdeps/x86_64/start.S:120
Address 0x7ffefb11af20 is located in stack of thread T0 at offset 32 in frame
#0 0x4e720f in main
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-3.c:6
This frame has 1 object(s):
[32, 36) 'a' <== Memory access at offset 32 is inside this variable
$ gcc -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-switch-3.c
-fsanitize=address -g && ./a.out
$
2) C++ temporaries
with /home/marxin/Programming/gcc/gcc/testsuite/g++.dg/asan/use-after-scope-3.C
$ clang++ -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/g++.dg/asan/use-after-scope-3.C
-std=c++11 && ./a.out
$
$ g++ -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/g++.dg/asan/use-after-scope-3.C
-std=c++11 && ./a.out
=================================================================
==11833==ERROR: AddressSanitizer: stack-use-after-scope on address
0x7fff509c9c80 at pc 0x0000004009b6 bp 0x7fff509c9c30 sp 0x7fff509c9c28
READ of size 4 at 0x7fff509c9c80 thread T0
#0 0x4009b5 in main (/tmp/a.out+0x4009b5)
#1 0x7fb1a971b290 in __libc_start_main (/lib64/libc.so.6+0x20290)
#2 0x4007d9 in _start (/tmp/a.out+0x4007d9)
...
3) store to memory
with:
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-10.c
$ clang -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-10.c
-fsanitize=address -g -O2 && ./a.out
$
$ gcc -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-10.c
-fsanitize=address -g -O2 && ./a.out
=================================================================
==14558==ERROR: AddressSanitizer: stack-use-after-scope on address
0x7fff3511ed20 at pc 0x0000004006d5 bp 0x7fff3511ecf0 sp 0x7fff3511ece8
WRITE of size 4 at 0x7fff3511ed20 thread T0
#0 0x4006d4 in main
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-10.c:16
#1 0x7fcb516c1290 in __libc_start_main (/lib64/libc.so.6+0x20290)
#2 0x400739 in _start (/tmp/a.out+0x400739)
Address 0x7fff3511ed20 is located in stack of thread T0 at offset 32 in frame
#0 0x40067f in main
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-10.c:7
This frame has 1 object(s):
[32, 36) 'a' <== Memory access at offset 32 is inside this variable
4) optimizing out some not necessary poisoning and unpoisoning:
$ clang -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-5.c
-fsanitize=address -O1 -S -o /dev/stdout | grep stack_memory
callq __asan_unpoison_stack_memory
callq __asan_poison_stack_memory
callq __asan_unpoison_stack_memory
$ gcc -fsanitize=address -fsanitize-address-use-after-scope
/home/marxin/Programming/gcc/gcc/testsuite/gcc.dg/asan/use-after-scope-5.c
-fsanitize=address -O1 -S -o /dev/stdout --param
use-after-scope-direct-emission-threshold=0 | grep stack_memory
Removing ASAN_MARK unpoison
call __asan_poison_stack_memory
Well I'm not convinced about this benefit on GCC's side. I would recommend to
remove this advantage.
Martin