On Tue, Feb 4, 2014 at 12:23 PM, Daniel Micay <[email protected]> wrote:
> On Tue, Feb 4, 2014 at 3:45 AM, Corey Richardson <[email protected]> wrote:
>> Hey all,
>>
>> As you are probably aware, we use LLVM for code generation and
>> optimization. It is a large project, and one of its cooler features is
>> the variety of "sanitizers" it provides
>> (http://clang.llvm.org/docs/index.html#using-clang-as-a-compiler).
>> These are not clang-specific, but indeed can be used with Rust!
>>
>> For example, to use AddressSanitizer (asan) on my system, I do:
>>
>>     rustc --passes asan,asan-module --link-args
>> "/usr/bin/../lib/clang/3.4/lib/linux/libclang_rt.asan-x86_64.a" foo.rs
>>
>> I got the path to the necessary asan library by looking at "clang -v
>> -fsanitize=address foo.c"
>>
>> For example, the following program:
>>
>> use std::libc::{free,malloc};
>>
>> fn main() {
>>     unsafe { let p = malloc(42); free(p); free(p); }
>> }
>>
>> Outputs https://gist.github.com/cmr/8800111
>>
>> Similarly, you can use ThreadSanitizer (tsan) by using `--passes tsan`
>> and replacing asan with tsan in the link-args. Also useful is msan
>> (for detecting uninitialized reads) and tsan (for detecting data
>> races). One caveat is that although LLVM will happily run all of the
>> sanitizer passes for you, you can actually only use one at a time (you
>> will see this when you try to link the multiple *san libraries
>> together).
>>
>> Now, these aren't going to be as useful in Rust given its focus on
>> safety, but they can still be useful when debugging unsafe code,
>> writing bindings, etc. Any time valgrind would be useful, often one of
>> the sanitizers can be used with less overhead.
>>
>> Cheers,
>> cmr
>
> This mostly doesn't work without frontend support. It's true that it
> will add checks to certain function calls, but the frontend support is
> missing so the majority of the feature set is not there. It will be
> unsafe to find out-of-bounds array access, out-of-bounds pointer
> arithmetic, dereferences of dangling pointers, data races and other
> problems originating in Rust code. No error is produced for the
> following:
>
>     fn main() {
>         unsafe {
>             let xs = [1, 2, 3];
>             xs.unsafe_ref(3);
>         }
>     }
>
> When using `clang`, you get the following error report:
>
> =================================================================
> ==15431==ERROR: AddressSanitizer: stack-buffer-overflow on address
> 0x7fff5cbe8eac at pc 0x47b92e bp 0x7fff5cbe8e10 sp 0x7fff5cbe8e08
> READ of size 4 at 0x7fff5cbe8eac thread T0
>     #0 0x47b92d in main (/home/strcat/a.out+0x47b92d)
>     #1 0x7ff1aecacb04 in __libc_start_main (/usr/lib/libc.so.6+0x21b04)
>     #2 0x47b5ec in _start (/home/strcat/a.out+0x47b5ec)
>
> Address 0x7fff5cbe8eac is located in stack of thread T0 at offset 44 in frame
>     #0 0x47b6bf in main (/home/strcat/a.out+0x47b6bf)
>
>   This frame has 1 object(s):
>     [32, 44) 'a' <== Memory access at offset 44 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-buffer-overflow ??:0 main
> Shadow bytes around the buggy address:
>   0x10006b975180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b975190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b9751a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b9751b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b9751c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> =>0x10006b9751d0: f1 f1 f1 f1 00[04]f4 f4 f3 f3 f3 f3 00 00 00 00
>   0x10006b9751e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b9751f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b975200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b975210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>   0x10006b975220: 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
>   ASan internal:         fe
> ==15431==ABORTING

Vadim brought this up at
https://github.com/mozilla/rust/issues/749#issuecomment-34040924. I'm
working on emitting the necessary stuff but the C API is a pain.
_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to