diff options
| author | Corey Farwell <coreyf@rwell.org> | 2017-02-08 23:55:43 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-02-08 23:55:43 -0500 |
| commit | 3053494a9ae79beffc8c3f3c4c1fdd3fd388be6a (patch) | |
| tree | adc1a7b05b2a2ce2c32718bd368ebbc05b594258 /src/test | |
| parent | 7f7dc764f5499f5caa45b8d5359609f55b8939d2 (diff) | |
| parent | e180dd541a8ae48e4aaf8934765f67955932252f (diff) | |
Rollup merge of #38699 - japaric:lsan, r=alexcrichton
LeakSanitizer, ThreadSanitizer, AddressSanitizer and MemorySanitizer support
```
$ cargo new --bin leak && cd $_
$ edit Cargo.toml && tail -n3 $_
```
``` toml
[profile.dev]
opt-level = 1
```
```
$ edit src/main.rs && cat $_
```
``` rust
use std::mem;
fn main() {
let xs = vec![0, 1, 2, 3];
mem::forget(xs);
}
```
```
$ RUSTFLAGS="-Z sanitizer=leak" cargo run --target x86_64-unknown-linux-gnu; echo $?
Finished dev [optimized + debuginfo] target(s) in 0.0 secs
Running `target/debug/leak`
=================================================================
==10848==ERROR: LeakSanitizer: detected memory leaks
Direct leak of 16 byte(s) in 1 object(s) allocated from:
#0 0x557c3488db1f in __interceptor_malloc /shared/rust/checkouts/lsan/src/compiler-rt/lib/lsan/lsan_interceptors.cc:55
#1 0x557c34888aaa in alloc::heap::exchange_malloc::h68f3f8b376a0da42 /shared/rust/checkouts/lsan/src/liballoc/heap.rs:138
#2 0x557c34888afc in leak::main::hc56ab767de6d653a $PWD/src/main.rs:4
#3 0x557c348c0806 in __rust_maybe_catch_panic ($PWD/target/debug/leak+0x3d806)
SUMMARY: LeakSanitizer: 16 byte(s) leaked in 1 allocation(s).
23
```
```
$ cargo new --bin racy && cd $_
$ edit src/main.rs && cat $_
```
``` rust
use std::thread;
static mut ANSWER: i32 = 0;
fn main() {
let t1 = thread::spawn(|| unsafe { ANSWER = 42 });
unsafe {
ANSWER = 24;
}
t1.join().ok();
}
```
```
$ RUSTFLAGS="-Z sanitizer=thread" cargo run --target x86_64-unknown-linux-gnu; echo $?
==================
WARNING: ThreadSanitizer: data race (pid=12019)
Write of size 4 at 0x562105989bb4 by thread T1:
#0 racy::main::_$u7b$$u7b$closure$u7d$$u7d$::hbe13ea9e8ac73f7e $PWD/src/main.rs:6 (racy+0x000000010e3f)
#1 _$LT$std..panic..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h2e466a92accacc78 /shared/rust/checkouts/lsan/src/libstd/panic.rs:296 (racy+0x000000010cc5)
#2 std::panicking::try::do_call::h7f4d2b38069e4042 /shared/rust/checkouts/lsan/src/libstd/panicking.rs:460 (racy+0x00000000c8f2)
#3 __rust_maybe_catch_panic <null> (racy+0x0000000b4e56)
#4 std::panic::catch_unwind::h31ca45621ad66d5a /shared/rust/checkouts/lsan/src/libstd/panic.rs:361 (racy+0x00000000b517)
#5 std::thread::Builder::spawn::_$u7b$$u7b$closure$u7d$$u7d$::hccfc37175dea0b01 /shared/rust/checkouts/lsan/src/libstd/thread/mod.rs:357 (racy+0x00000000c226)
#6 _$LT$F$u20$as$u20$alloc..boxed..FnBox$LT$A$GT$$GT$::call_box::hd880bbf91561e033 /shared/rust/checkouts/lsan/src/liballoc/boxed.rs:605 (racy+0x00000000f27e)
#7 std::sys::imp::thread::Thread::new::thread_start::hebdfc4b3d17afc85 <null> (racy+0x0000000abd40)
Previous write of size 4 at 0x562105989bb4 by main thread:
#0 racy::main::h23e6e5ca46d085c3 $PWD/src/main.rs:8 (racy+0x000000010d7c)
#1 __rust_maybe_catch_panic <null> (racy+0x0000000b4e56)
#2 __libc_start_main <null> (libc.so.6+0x000000020290)
Location is global 'racy::ANSWER::h543d2b139f819b19' of size 4 at 0x562105989bb4 (racy+0x0000002f8bb4)
Thread T1 (tid=12028, running) created by main thread at:
#0 pthread_create /shared/rust/checkouts/lsan/src/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc:902 (racy+0x00000001aedb)
#1 std::sys::imp::thread::Thread::new::hce44187bf4a36222 <null> (racy+0x0000000ab9ae)
#2 std::thread::spawn::he382608373eb667e /shared/rust/checkouts/lsan/src/libstd/thread/mod.rs:412 (racy+0x00000000b5aa)
#3 racy::main::h23e6e5ca46d085c3 $PWD/src/main.rs:6 (racy+0x000000010d5c)
#4 __rust_maybe_catch_panic <null> (racy+0x0000000b4e56)
#5 __libc_start_main <null> (libc.so.6+0x000000020290)
SUMMARY: ThreadSanitizer: data race $PWD/src/main.rs:6 in racy::main::_$u7b$$u7b$closure$u7d$$u7d$::hbe13ea9e8ac73f7e
==================
ThreadSanitizer: reported 1 warnings
66
```
```
$ cargo new --bin oob && cd $_
$ edit src/main.rs && cat $_
```
``` rust
fn main() {
let xs = [0, 1, 2, 3];
let y = unsafe { *xs.as_ptr().offset(4) };
}
```
```
$ RUSTFLAGS="-Z sanitizer=address" cargo run --target x86_64-unknown-linux-gnu; echo $?
=================================================================
==13328==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff29f3ecd0 at pc 0x55802dc6bf7e bp 0x7fff29f3ec90 sp 0x7fff29f3ec88
READ of size 4 at 0x7fff29f3ecd0 thread T0
#0 0x55802dc6bf7d in oob::main::h0adc7b67e5feb2e7 $PWD/src/main.rs:3
#1 0x55802dd60426 in __rust_maybe_catch_panic ($PWD/target/debug/oob+0xfe426)
#2 0x55802dd58dd9 in std::rt::lang_start::hb2951fc8a59d62a7 ($PWD/target/debug/oob+0xf6dd9)
#3 0x55802dc6c002 in main ($PWD/target/debug/oob+0xa002)
#4 0x7fad8c3b3290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#5 0x55802dc6b719 in _start ($PWD/target/debug/oob+0x9719)
Address 0x7fff29f3ecd0 is located in stack of thread T0 at offset 48 in frame
#0 0x55802dc6bd5f in oob::main::h0adc7b67e5feb2e7 $PWD/src/main.rs:1
This frame has 1 object(s):
[32, 48) 'xs' <== Memory access at offset 48 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 $PWD/src/main.rs:3 in oob::main::h0adc7b67e5feb2e7
Shadow bytes around the buggy address:
0x1000653dfd40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfd50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfd60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfd70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfd80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x1000653dfd90: 00 00 00 00 f1 f1 f1 f1 00 00[f3]f3 00 00 00 00
0x1000653dfda0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfdb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfdc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfdd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000653dfde0: 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
==13328==ABORTING
1
```
```
$ cargo new --bin uninit && cd $_
$ edit src/main.rs && cat $_
```
``` rust
use std::mem;
fn main() {
let xs: [u8; 4] = unsafe { mem::uninitialized() };
let y = xs[0] + xs[1];
}
```
```
$ RUSTFLAGS="-Z sanitizer=memory" cargo run; echo $?
==30198==WARNING: MemorySanitizer: use-of-uninitialized-value
#0 0x563f4b6867da in uninit::main::hc2731cd4f2ed48f8 $PWD/src/main.rs:5
#1 0x563f4b7033b6 in __rust_maybe_catch_panic ($PWD/target/debug/uninit+0x873b6)
#2 0x563f4b6fbd69 in std::rt::lang_start::hb2951fc8a59d62a7 ($PWD/target/debug/uninit+0x7fd69)
#3 0x563f4b6868a9 in main ($PWD/target/debug/uninit+0xa8a9)
#4 0x7fe844354290 in __libc_start_main (/usr/lib/libc.so.6+0x20290)
#5 0x563f4b6864f9 in _start ($PWD/target/debug/uninit+0xa4f9)
SUMMARY: MemorySanitizer: use-of-uninitialized-value $PWD/src/main.rs:5 in uninit::main::hc2731cd4f2ed48f8
Exiting
77
```
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/compile-fail/feature-gate-sanitizer-runtime.rs | 13 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-address/Makefile | 11 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-address/overflow.rs | 14 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-dylib/Makefile | 8 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-dylib/hello.rs | 13 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-invalid-target/Makefile | 4 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-invalid-target/hello.rs | 13 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-leak/Makefile | 10 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-leak/leak.rs | 16 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-memory/Makefile | 10 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-memory/uninit.rs | 16 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-thread/Makefile | 10 | ||||
| -rw-r--r-- | src/test/run-make/sanitizer-thread/racy.rs | 21 |
13 files changed, 159 insertions, 0 deletions
diff --git a/src/test/compile-fail/feature-gate-sanitizer-runtime.rs b/src/test/compile-fail/feature-gate-sanitizer-runtime.rs new file mode 100644 index 00000000000..a18641d8246 --- /dev/null +++ b/src/test/compile-fail/feature-gate-sanitizer-runtime.rs @@ -0,0 +1,13 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![sanitizer_runtime] //~ ERROR the `#[sanitizer_runtime]` attribute is + +fn main() {} diff --git a/src/test/run-make/sanitizer-address/Makefile b/src/test/run-make/sanitizer-address/Makefile new file mode 100644 index 00000000000..5931145f3a4 --- /dev/null +++ b/src/test/run-make/sanitizer-address/Makefile @@ -0,0 +1,11 @@ +-include ../tools.mk + +# NOTE the address sanitizer only supports x86_64 linux +ifdef SANITIZER_SUPPORT +all: + $(RUSTC) -g -Z sanitizer=address -Z print-link-args overflow.rs | grep -q librustc_asan + $(TMPDIR)/overflow 2>&1 | grep -q stack-buffer-overflow +else +all: + +endif diff --git a/src/test/run-make/sanitizer-address/overflow.rs b/src/test/run-make/sanitizer-address/overflow.rs new file mode 100644 index 00000000000..e35c3873f7e --- /dev/null +++ b/src/test/run-make/sanitizer-address/overflow.rs @@ -0,0 +1,14 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + let xs = [0, 1, 2, 3]; + let y = unsafe { *xs.as_ptr().offset(4) }; +} diff --git a/src/test/run-make/sanitizer-dylib/Makefile b/src/test/run-make/sanitizer-dylib/Makefile new file mode 100644 index 00000000000..835d5b0d9d8 --- /dev/null +++ b/src/test/run-make/sanitizer-dylib/Makefile @@ -0,0 +1,8 @@ +-include ../tools.mk + +ifeq ($(TARGET),x86_64-unknown-linux-gnu) +all: + $(RUSTC) -Z sanitizer=leak --crate-type dylib --target $(TARGET) hello.rs 2>&1 | grep -q 'Only executables and rlibs can be compiled with `-Z sanitizer`' +else +all: +endif diff --git a/src/test/run-make/sanitizer-dylib/hello.rs b/src/test/run-make/sanitizer-dylib/hello.rs new file mode 100644 index 00000000000..41782851a1a --- /dev/null +++ b/src/test/run-make/sanitizer-dylib/hello.rs @@ -0,0 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/run-make/sanitizer-invalid-target/Makefile b/src/test/run-make/sanitizer-invalid-target/Makefile new file mode 100644 index 00000000000..6a1ce8bab2f --- /dev/null +++ b/src/test/run-make/sanitizer-invalid-target/Makefile @@ -0,0 +1,4 @@ +-include ../tools.mk + +all: + $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | grep -q 'Sanitizers only work with the `x86_64-unknown-linux-gnu` target' diff --git a/src/test/run-make/sanitizer-invalid-target/hello.rs b/src/test/run-make/sanitizer-invalid-target/hello.rs new file mode 100644 index 00000000000..e9e46b7702a --- /dev/null +++ b/src/test/run-make/sanitizer-invalid-target/hello.rs @@ -0,0 +1,13 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/src/test/run-make/sanitizer-leak/Makefile b/src/test/run-make/sanitizer-leak/Makefile new file mode 100644 index 00000000000..f02d948fdc8 --- /dev/null +++ b/src/test/run-make/sanitizer-leak/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +ifdef SANITIZER_SUPPORT +all: + $(RUSTC) -C opt-level=1 -g -Z sanitizer=leak -Z print-link-args leak.rs | grep -q librustc_lsan + $(TMPDIR)/leak 2>&1 | grep -q 'detected memory leaks' +else +all: + +endif diff --git a/src/test/run-make/sanitizer-leak/leak.rs b/src/test/run-make/sanitizer-leak/leak.rs new file mode 100644 index 00000000000..279da6aaae7 --- /dev/null +++ b/src/test/run-make/sanitizer-leak/leak.rs @@ -0,0 +1,16 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +fn main() { + let xs = vec![1, 2, 3, 4]; + mem::forget(xs); +} diff --git a/src/test/run-make/sanitizer-memory/Makefile b/src/test/run-make/sanitizer-memory/Makefile new file mode 100644 index 00000000000..08682e5975e --- /dev/null +++ b/src/test/run-make/sanitizer-memory/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +ifdef SANITIZER_SUPPORT +all: + $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | grep -q librustc_msan + $(TMPDIR)/uninit 2>&1 | grep -q use-of-uninitialized-value +else +all: + +endif diff --git a/src/test/run-make/sanitizer-memory/uninit.rs b/src/test/run-make/sanitizer-memory/uninit.rs new file mode 100644 index 00000000000..8350c7de3ac --- /dev/null +++ b/src/test/run-make/sanitizer-memory/uninit.rs @@ -0,0 +1,16 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::mem; + +fn main() { + let xs: [u8; 4] = unsafe { mem::uninitialized() }; + let y = xs[0] + xs[1]; +} diff --git a/src/test/run-make/sanitizer-thread/Makefile b/src/test/run-make/sanitizer-thread/Makefile new file mode 100644 index 00000000000..8bb89a241cb --- /dev/null +++ b/src/test/run-make/sanitizer-thread/Makefile @@ -0,0 +1,10 @@ +-include ../tools.mk + +ifdef SANITIZER_SUPPORT +all: + $(RUSTC) -g -Z sanitizer=thread -Z print-link-args racy.rs | grep -q librustc_tsan + $(TMPDIR)/racy 2>&1 | grep -q 'data race' +else +all: + +endif diff --git a/src/test/run-make/sanitizer-thread/racy.rs b/src/test/run-make/sanitizer-thread/racy.rs new file mode 100644 index 00000000000..dc929e004a4 --- /dev/null +++ b/src/test/run-make/sanitizer-thread/racy.rs @@ -0,0 +1,21 @@ +// Copyright 2017 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::thread; + +static mut ANSWER: i32 = 0; + +fn main() { + let t1 = thread::spawn(|| unsafe { ANSWER = 42 }); + unsafe { + ANSWER = 24; + } + t1.join().ok(); +} |
