summaryrefslogtreecommitdiffstats
path: root/tests/ui/sanitize
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/sanitize
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/sanitize')
-rw-r--r--tests/ui/sanitize/address.rs18
-rw-r--r--tests/ui/sanitize/badfree.rs19
-rw-r--r--tests/ui/sanitize/cfg.rs28
-rw-r--r--tests/ui/sanitize/crt-static.rs6
-rw-r--r--tests/ui/sanitize/crt-static.stderr4
-rw-r--r--tests/ui/sanitize/hwaddress.rs21
-rw-r--r--tests/ui/sanitize/incompatible.rs7
-rw-r--r--tests/ui/sanitize/incompatible.stderr4
-rw-r--r--tests/ui/sanitize/inline-always.rs15
-rw-r--r--tests/ui/sanitize/inline-always.stderr15
-rw-r--r--tests/ui/sanitize/issue-72154-lifetime-markers.rs31
-rw-r--r--tests/ui/sanitize/leak.rs19
-rw-r--r--tests/ui/sanitize/memory-eager.rs37
-rw-r--r--tests/ui/sanitize/memory-passing.rs32
-rw-r--r--tests/ui/sanitize/memory.rs46
-rw-r--r--tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs26
-rw-r--r--tests/ui/sanitize/thread.rs57
-rw-r--r--tests/ui/sanitize/unsupported-target.rs6
-rw-r--r--tests/ui/sanitize/unsupported-target.stderr4
-rw-r--r--tests/ui/sanitize/use-after-scope.rs18
20 files changed, 413 insertions, 0 deletions
diff --git a/tests/ui/sanitize/address.rs b/tests/ui/sanitize/address.rs
new file mode 100644
index 000000000..5b2cea875
--- /dev/null
+++ b/tests/ui/sanitize/address.rs
@@ -0,0 +1,18 @@
+// needs-sanitizer-support
+// needs-sanitizer-address
+//
+// compile-flags: -Z sanitizer=address -O -g
+//
+// run-fail
+// error-pattern: AddressSanitizer: stack-buffer-overflow
+// error-pattern: 'xs' (line 13) <== Memory access at offset
+
+use std::hint::black_box;
+
+fn main() {
+ let xs = [0, 1, 2, 3];
+ // Avoid optimizing everything out.
+ let xs = black_box(xs.as_ptr());
+ let code = unsafe { *xs.offset(4) };
+ std::process::exit(code);
+}
diff --git a/tests/ui/sanitize/badfree.rs b/tests/ui/sanitize/badfree.rs
new file mode 100644
index 000000000..095a6f469
--- /dev/null
+++ b/tests/ui/sanitize/badfree.rs
@@ -0,0 +1,19 @@
+// needs-sanitizer-support
+// needs-sanitizer-address
+//
+// compile-flags: -Z sanitizer=address -O
+//
+// run-fail
+// error-pattern: AddressSanitizer: SEGV
+
+use std::ffi::c_void;
+
+extern "C" {
+ fn free(ptr: *mut c_void);
+}
+
+fn main() {
+ unsafe {
+ free(1 as *mut c_void);
+ }
+}
diff --git a/tests/ui/sanitize/cfg.rs b/tests/ui/sanitize/cfg.rs
new file mode 100644
index 000000000..79dfe58f0
--- /dev/null
+++ b/tests/ui/sanitize/cfg.rs
@@ -0,0 +1,28 @@
+// Verifies that when compiling with -Zsanitizer=option,
+// the `#[cfg(sanitize = "option")]` attribute is configured.
+
+// needs-sanitizer-support
+// needs-sanitizer-address
+// needs-sanitizer-leak
+// needs-sanitizer-memory
+// needs-sanitizer-thread
+// check-pass
+// revisions: address leak memory thread
+//[address]compile-flags: -Zsanitizer=address --cfg address
+//[leak]compile-flags: -Zsanitizer=leak --cfg leak
+//[memory]compile-flags: -Zsanitizer=memory --cfg memory
+//[thread]compile-flags: -Zsanitizer=thread --cfg thread
+
+#![feature(cfg_sanitize)]
+
+#[cfg(all(sanitize = "address", address))]
+fn main() {}
+
+#[cfg(all(sanitize = "leak", leak))]
+fn main() {}
+
+#[cfg(all(sanitize = "memory", memory))]
+fn main() {}
+
+#[cfg(all(sanitize = "thread", thread))]
+fn main() {}
diff --git a/tests/ui/sanitize/crt-static.rs b/tests/ui/sanitize/crt-static.rs
new file mode 100644
index 000000000..7a6b9eda3
--- /dev/null
+++ b/tests/ui/sanitize/crt-static.rs
@@ -0,0 +1,6 @@
+// compile-flags: -Z sanitizer=address -C target-feature=+crt-static --target x86_64-unknown-linux-gnu
+// needs-llvm-components: x86
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitize/crt-static.stderr b/tests/ui/sanitize/crt-static.stderr
new file mode 100644
index 000000000..9f74235fe
--- /dev/null
+++ b/tests/ui/sanitize/crt-static.stderr
@@ -0,0 +1,4 @@
+error: sanitizer is incompatible with statically linked libc, disable it using `-C target-feature=-crt-static`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/sanitize/hwaddress.rs b/tests/ui/sanitize/hwaddress.rs
new file mode 100644
index 000000000..f9b37a155
--- /dev/null
+++ b/tests/ui/sanitize/hwaddress.rs
@@ -0,0 +1,21 @@
+// needs-sanitizer-support
+// needs-sanitizer-hwaddress
+//
+// FIXME(#83706): this test triggers errors on aarch64-gnu
+// ignore-aarch64-unknown-linux-gnu
+//
+// FIXME(#83989): codegen-units=1 triggers linker errors on aarch64-gnu
+// compile-flags: -Z sanitizer=hwaddress -O -g -C codegen-units=16
+//
+// run-fail
+// error-pattern: HWAddressSanitizer: tag-mismatch
+
+use std::hint::black_box;
+
+fn main() {
+ let xs = vec![0, 1, 2, 3];
+ // Avoid optimizing everything out.
+ let xs = black_box(xs.as_ptr());
+ let code = unsafe { *xs.offset(4) };
+ std::process::exit(code);
+}
diff --git a/tests/ui/sanitize/incompatible.rs b/tests/ui/sanitize/incompatible.rs
new file mode 100644
index 000000000..bcafc2891
--- /dev/null
+++ b/tests/ui/sanitize/incompatible.rs
@@ -0,0 +1,7 @@
+// compile-flags: -Z sanitizer=address -Z sanitizer=memory --target x86_64-unknown-linux-gnu
+// needs-llvm-components: x86
+// error-pattern: error: `-Zsanitizer=address` is incompatible with `-Zsanitizer=memory`
+
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitize/incompatible.stderr b/tests/ui/sanitize/incompatible.stderr
new file mode 100644
index 000000000..f86db41ba
--- /dev/null
+++ b/tests/ui/sanitize/incompatible.stderr
@@ -0,0 +1,4 @@
+error: `-Zsanitizer=address` is incompatible with `-Zsanitizer=memory`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/sanitize/inline-always.rs b/tests/ui/sanitize/inline-always.rs
new file mode 100644
index 000000000..52dc55781
--- /dev/null
+++ b/tests/ui/sanitize/inline-always.rs
@@ -0,0 +1,15 @@
+// check-pass
+
+#![feature(no_sanitize)]
+
+#[inline(always)]
+//~^ NOTE inlining requested here
+#[no_sanitize(address)]
+//~^ WARN will have no effect after inlining
+//~| NOTE on by default
+fn x() {
+}
+
+fn main() {
+ x()
+}
diff --git a/tests/ui/sanitize/inline-always.stderr b/tests/ui/sanitize/inline-always.stderr
new file mode 100644
index 000000000..74fba3c0e
--- /dev/null
+++ b/tests/ui/sanitize/inline-always.stderr
@@ -0,0 +1,15 @@
+warning: `no_sanitize` will have no effect after inlining
+ --> $DIR/inline-always.rs:7:1
+ |
+LL | #[no_sanitize(address)]
+ | ^^^^^^^^^^^^^^^^^^^^^^^
+ |
+note: inlining requested here
+ --> $DIR/inline-always.rs:5:1
+ |
+LL | #[inline(always)]
+ | ^^^^^^^^^^^^^^^^^
+ = note: `#[warn(inline_no_sanitize)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/sanitize/issue-72154-lifetime-markers.rs b/tests/ui/sanitize/issue-72154-lifetime-markers.rs
new file mode 100644
index 000000000..b2e182238
--- /dev/null
+++ b/tests/ui/sanitize/issue-72154-lifetime-markers.rs
@@ -0,0 +1,31 @@
+// Regression test for issue 72154, where the use of AddressSanitizer enabled
+// emission of lifetime markers during codegen, while at the same time asking
+// always inliner pass not to insert them. This eventually lead to a
+// miscompilation which was subsequently detected by AddressSanitizer as UB.
+//
+// needs-sanitizer-support
+// needs-sanitizer-address
+//
+// compile-flags: -Copt-level=0 -Zsanitizer=address
+// run-pass
+
+pub struct Wrap {
+ pub t: [usize; 1]
+}
+
+impl Wrap {
+ #[inline(always)]
+ pub fn new(t: [usize; 1]) -> Self {
+ Wrap { t }
+ }
+}
+
+#[inline(always)]
+pub fn assume_init() -> [usize; 1] {
+ [1234]
+}
+
+fn main() {
+ let x: [usize; 1] = assume_init();
+ Wrap::new(x);
+}
diff --git a/tests/ui/sanitize/leak.rs b/tests/ui/sanitize/leak.rs
new file mode 100644
index 000000000..cbb44ae8a
--- /dev/null
+++ b/tests/ui/sanitize/leak.rs
@@ -0,0 +1,19 @@
+// needs-sanitizer-support
+// needs-sanitizer-leak
+//
+// compile-flags: -Z sanitizer=leak -O
+//
+// run-fail
+// error-pattern: LeakSanitizer: detected memory leaks
+
+use std::hint::black_box;
+use std::mem;
+
+fn main() {
+ for _ in 0..10 {
+ let xs = vec![1, 2, 3];
+ // Prevent compiler from removing the memory allocation.
+ let xs = black_box(xs);
+ mem::forget(xs);
+ }
+}
diff --git a/tests/ui/sanitize/memory-eager.rs b/tests/ui/sanitize/memory-eager.rs
new file mode 100644
index 000000000..0018c2f75
--- /dev/null
+++ b/tests/ui/sanitize/memory-eager.rs
@@ -0,0 +1,37 @@
+// needs-sanitizer-support
+// needs-sanitizer-memory
+// min-llvm-version: 14.0.0
+//
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
+//
+// run-fail
+// error-pattern: MemorySanitizer: use-of-uninitialized-value
+// error-pattern: Uninitialized value was created by an allocation
+// error-pattern: in the stack frame
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+
+use std::hint::black_box;
+use std::mem::MaybeUninit;
+
+#[inline(never)]
+#[no_mangle]
+#[allow(invalid_value)]
+fn random() -> char {
+ let r = unsafe { MaybeUninit::uninit().assume_init() };
+ // Avoid optimizing everything out.
+ black_box(r)
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+ random();
+ 0
+}
diff --git a/tests/ui/sanitize/memory-passing.rs b/tests/ui/sanitize/memory-passing.rs
new file mode 100644
index 000000000..6d9b70ad6
--- /dev/null
+++ b/tests/ui/sanitize/memory-passing.rs
@@ -0,0 +1,32 @@
+// needs-sanitizer-support
+// needs-sanitizer-memory
+//
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
+//
+// run-pass
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+#![allow(invalid_value)]
+
+use std::hint::black_box;
+
+fn calling_black_box_on_zst_ok() {
+ // It's OK to call black_box on a value of a zero-sized type, even if its
+ // underlying the memory location is uninitialized. For non-zero-sized types,
+ // this would be an MSAN error.
+ let zst = ();
+ black_box(zst);
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+ calling_black_box_on_zst_ok();
+ 0
+}
diff --git a/tests/ui/sanitize/memory.rs b/tests/ui/sanitize/memory.rs
new file mode 100644
index 000000000..1a9ac3a4f
--- /dev/null
+++ b/tests/ui/sanitize/memory.rs
@@ -0,0 +1,46 @@
+// needs-sanitizer-support
+// needs-sanitizer-memory
+//
+// revisions: unoptimized optimized
+//
+// [optimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O
+// [unoptimized]compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins
+//
+// run-fail
+// error-pattern: MemorySanitizer: use-of-uninitialized-value
+// error-pattern: Uninitialized value was created by an allocation
+// error-pattern: in the stack frame
+//
+// This test case intentionally limits the usage of the std,
+// since it will be linked with an uninstrumented version of it.
+
+#![feature(core_intrinsics)]
+#![feature(start)]
+#![allow(invalid_value)]
+
+use std::hint::black_box;
+use std::mem::MaybeUninit;
+
+#[inline(never)]
+#[no_mangle]
+fn random() -> [isize; 32] {
+ let r = MaybeUninit::uninit();
+ // Avoid optimizing everything out.
+ unsafe { std::intrinsics::volatile_load(r.as_ptr()) }
+}
+
+#[inline(never)]
+#[no_mangle]
+fn xor(a: &[isize]) -> isize {
+ let mut s = 0;
+ for i in 0..a.len() {
+ s = s ^ a[i];
+ }
+ s
+}
+
+#[start]
+fn main(_: isize, _: *const *const u8) -> isize {
+ let r = black_box(random as fn() -> [isize; 32])();
+ xor(&r)
+}
diff --git a/tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs b/tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs
new file mode 100644
index 000000000..33e18e355
--- /dev/null
+++ b/tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs
@@ -0,0 +1,26 @@
+// Regression test for sanitizer function instrumentation passes not
+// being run when compiling with new LLVM pass manager and ThinLTO.
+// Note: The issue occurred only on non-zero opt-level.
+//
+// needs-sanitizer-support
+// needs-sanitizer-address
+//
+// no-prefer-dynamic
+// revisions: opt0 opt1
+// compile-flags: -Zsanitizer=address -Clto=thin
+//[opt0]compile-flags: -Copt-level=0
+//[opt1]compile-flags: -Copt-level=1
+// run-fail
+// error-pattern: ERROR: AddressSanitizer: stack-use-after-scope
+
+static mut P: *mut usize = std::ptr::null_mut();
+
+fn main() {
+ unsafe {
+ {
+ let mut x = 0;
+ P = &mut x;
+ }
+ std::ptr::write_volatile(P, 123);
+ }
+}
diff --git a/tests/ui/sanitize/thread.rs b/tests/ui/sanitize/thread.rs
new file mode 100644
index 000000000..c70cf5acc
--- /dev/null
+++ b/tests/ui/sanitize/thread.rs
@@ -0,0 +1,57 @@
+// Verifies that ThreadSanitizer is able to detect a data race in heap allocated
+// memory block.
+//
+// Test case minimizes the use of the standard library to avoid its ambiguous
+// status with respect to instrumentation (it could vary depending on whatever
+// a function call is inlined or not).
+//
+// The conflicting data access is de-facto synchronized with a special TSAN
+// barrier, which does not introduce synchronization from TSAN perspective, but
+// is necessary to make the test robust. Without the barrier data race detection
+// would occasionally fail, making test flaky.
+//
+// needs-sanitizer-support
+// needs-sanitizer-thread
+//
+// compile-flags: -Z sanitizer=thread -O
+//
+// run-fail
+// error-pattern: WARNING: ThreadSanitizer: data race
+// error-pattern: Location is heap block of size 4
+// error-pattern: allocated by main thread
+
+#![feature(raw_ref_op)]
+#![feature(rustc_private)]
+extern crate libc;
+
+use std::mem;
+use std::ptr;
+
+static mut BARRIER: u64 = 0;
+
+extern "C" {
+ fn __tsan_testonly_barrier_init(barrier: *mut u64, count: u32);
+ fn __tsan_testonly_barrier_wait(barrier: *mut u64);
+}
+
+extern "C" fn start(c: *mut libc::c_void) -> *mut libc::c_void {
+ unsafe {
+ let c: *mut u32 = c.cast();
+ *c += 1;
+ __tsan_testonly_barrier_wait(&raw mut BARRIER);
+ ptr::null_mut()
+ }
+}
+
+fn main() {
+ unsafe {
+ __tsan_testonly_barrier_init(&raw mut BARRIER, 2);
+ let c: *mut u32 = Box::into_raw(Box::new(1));
+ let mut t: libc::pthread_t = mem::zeroed();
+ libc::pthread_create(&mut t, ptr::null(), start, c.cast());
+ __tsan_testonly_barrier_wait(&raw mut BARRIER);
+ *c += 1;
+ libc::pthread_join(t, ptr::null_mut());
+ Box::from_raw(c);
+ }
+}
diff --git a/tests/ui/sanitize/unsupported-target.rs b/tests/ui/sanitize/unsupported-target.rs
new file mode 100644
index 000000000..9f29c7635
--- /dev/null
+++ b/tests/ui/sanitize/unsupported-target.rs
@@ -0,0 +1,6 @@
+// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu
+// needs-llvm-components: x86
+// error-pattern: error: leak sanitizer is not supported for this target
+#![feature(no_core)]
+#![no_core]
+#![no_main]
diff --git a/tests/ui/sanitize/unsupported-target.stderr b/tests/ui/sanitize/unsupported-target.stderr
new file mode 100644
index 000000000..9bb840502
--- /dev/null
+++ b/tests/ui/sanitize/unsupported-target.stderr
@@ -0,0 +1,4 @@
+error: leak sanitizer is not supported for this target
+
+error: aborting due to previous error
+
diff --git a/tests/ui/sanitize/use-after-scope.rs b/tests/ui/sanitize/use-after-scope.rs
new file mode 100644
index 000000000..30be2ae6f
--- /dev/null
+++ b/tests/ui/sanitize/use-after-scope.rs
@@ -0,0 +1,18 @@
+// needs-sanitizer-support
+// needs-sanitizer-address
+//
+// compile-flags: -Zsanitizer=address
+// run-fail
+// error-pattern: ERROR: AddressSanitizer: stack-use-after-scope
+
+static mut P: *mut usize = std::ptr::null_mut();
+
+fn main() {
+ unsafe {
+ {
+ let mut x = 0;
+ P = &mut x;
+ }
+ std::ptr::write_volatile(P, 123);
+ }
+}