From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/sanitize/address.rs | 18 +++++++ tests/ui/sanitize/badfree.rs | 19 ++++++++ tests/ui/sanitize/cfg.rs | 28 +++++++++++ tests/ui/sanitize/crt-static.rs | 6 +++ tests/ui/sanitize/crt-static.stderr | 4 ++ tests/ui/sanitize/hwaddress.rs | 21 ++++++++ tests/ui/sanitize/incompatible.rs | 7 +++ tests/ui/sanitize/incompatible.stderr | 4 ++ tests/ui/sanitize/inline-always.rs | 15 ++++++ tests/ui/sanitize/inline-always.stderr | 15 ++++++ tests/ui/sanitize/issue-72154-lifetime-markers.rs | 31 ++++++++++++ tests/ui/sanitize/leak.rs | 19 ++++++++ tests/ui/sanitize/memory-eager.rs | 37 ++++++++++++++ tests/ui/sanitize/memory-passing.rs | 32 ++++++++++++ tests/ui/sanitize/memory.rs | 46 +++++++++++++++++ .../ui/sanitize/new-llvm-pass-manager-thin-lto.rs | 26 ++++++++++ tests/ui/sanitize/thread.rs | 57 ++++++++++++++++++++++ tests/ui/sanitize/unsupported-target.rs | 6 +++ tests/ui/sanitize/unsupported-target.stderr | 4 ++ tests/ui/sanitize/use-after-scope.rs | 18 +++++++ 20 files changed, 413 insertions(+) create mode 100644 tests/ui/sanitize/address.rs create mode 100644 tests/ui/sanitize/badfree.rs create mode 100644 tests/ui/sanitize/cfg.rs create mode 100644 tests/ui/sanitize/crt-static.rs create mode 100644 tests/ui/sanitize/crt-static.stderr create mode 100644 tests/ui/sanitize/hwaddress.rs create mode 100644 tests/ui/sanitize/incompatible.rs create mode 100644 tests/ui/sanitize/incompatible.stderr create mode 100644 tests/ui/sanitize/inline-always.rs create mode 100644 tests/ui/sanitize/inline-always.stderr create mode 100644 tests/ui/sanitize/issue-72154-lifetime-markers.rs create mode 100644 tests/ui/sanitize/leak.rs create mode 100644 tests/ui/sanitize/memory-eager.rs create mode 100644 tests/ui/sanitize/memory-passing.rs create mode 100644 tests/ui/sanitize/memory.rs create mode 100644 tests/ui/sanitize/new-llvm-pass-manager-thin-lto.rs create mode 100644 tests/ui/sanitize/thread.rs create mode 100644 tests/ui/sanitize/unsupported-target.rs create mode 100644 tests/ui/sanitize/unsupported-target.stderr create mode 100644 tests/ui/sanitize/use-after-scope.rs (limited to 'tests/ui/sanitize') 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); + } +} -- cgit v1.2.3