diff --git a/ci.sh b/ci.sh index 1b3ed796c6..eda1ceb408 100755 --- a/ci.sh +++ b/ci.sh @@ -110,8 +110,8 @@ case $HOST_TARGET in MIRI_TEST_TARGET=i686-pc-windows-gnu run_tests MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic - MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings - MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings + MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer strings wasm + MIRI_TEST_TARGET=wasm32-unknown-unknown run_tests_minimal no_std integer strings wasm MIRI_TEST_TARGET=thumbv7em-none-eabihf run_tests_minimal no_std # no_std embedded architecture MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file ;; diff --git a/rust-version b/rust-version index 474e7da000..a7c9d720c0 100644 --- a/rust-version +++ b/rust-version @@ -1 +1 @@ -2a7c2df506fcd5611967a203cc994da5f21abd1e +c07693c1608258f3577eb15057fc0744fa924ae9 diff --git a/src/borrow_tracker/stacked_borrows/mod.rs b/src/borrow_tracker/stacked_borrows/mod.rs index 66b729fb16..a74c69d52f 100644 --- a/src/borrow_tracker/stacked_borrows/mod.rs +++ b/src/borrow_tracker/stacked_borrows/mod.rs @@ -14,7 +14,7 @@ use log::trace; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir::{Mutability, RetagKind}; use rustc_middle::ty::{self, layout::HasParamEnv, Ty}; -use rustc_target::abi::{Abi, Align, Size}; +use rustc_target::abi::{Abi, Size}; use crate::borrow_tracker::{ stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder}, @@ -616,7 +616,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' ) -> InterpResult<'tcx, Option> { let this = self.eval_context_mut(); // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050). - this.check_ptr_access_align(place.ptr(), size, Align::ONE, CheckInAllocMsg::InboundsTest)?; + this.check_ptr_access(place.ptr(), size, CheckInAllocMsg::InboundsTest)?; // It is crucial that this gets called on all code paths, to ensure we track tag creation. let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, diff --git a/src/borrow_tracker/tree_borrows/mod.rs b/src/borrow_tracker/tree_borrows/mod.rs index 6d4c573a35..e902939290 100644 --- a/src/borrow_tracker/tree_borrows/mod.rs +++ b/src/borrow_tracker/tree_borrows/mod.rs @@ -1,6 +1,6 @@ use log::trace; -use rustc_target::abi::{Abi, Align, Size}; +use rustc_target::abi::{Abi, Size}; use crate::borrow_tracker::{ AccessKind, GlobalState, GlobalStateInner, ProtectorKind, RetagFields, @@ -206,12 +206,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<' // Make sure the new permission makes sense as the initial permission of a fresh tag. assert!(new_perm.initial_state.is_initial()); // Ensure we bail out if the pointer goes out-of-bounds (see miri#1050). - this.check_ptr_access_align( - place.ptr(), - ptr_size, - Align::ONE, - CheckInAllocMsg::InboundsTest, - )?; + this.check_ptr_access(place.ptr(), ptr_size, CheckInAllocMsg::InboundsTest)?; // It is crucial that this gets called on all code paths, to ensure we track tag creation. let log_creation = |this: &MiriInterpCx<'mir, 'tcx>, diff --git a/src/concurrency/data_race.rs b/src/concurrency/data_race.rs index 24b9fa0776..bec2972c50 100644 --- a/src/concurrency/data_race.rs +++ b/src/concurrency/data_race.rs @@ -1017,12 +1017,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriInterpCxExt<'mir, 'tcx> { // even if the type they wrap would be less aligned (e.g. AtomicU64 on 32bit must // be 8-aligned). let align = Align::from_bytes(place.layout.size.bytes()).unwrap(); - this.check_ptr_access_align( - place.ptr(), - place.layout.size, - align, - CheckInAllocMsg::MemoryAccessTest, - )?; + this.check_ptr_align(place.ptr(), align)?; // Ensure the allocation is mutable. Even failing (read-only) compare_exchange need mutable // memory on many targets (i.e., they segfault if taht memory is mapped read-only), and // atomic loads can be implemented via compare_exchange on some targets. There could diff --git a/src/helpers.rs b/src/helpers.rs index 4146a9b41a..fd75e8b0ca 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -697,27 +697,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { let this = self.eval_context_ref(); let ptr = this.read_pointer(op)?; - - let mplace = MPlaceTy::from_aligned_ptr(ptr, layout); - - this.check_mplace(&mplace)?; - - Ok(mplace) - } - - /// Deref' a pointer *without* checking that the place is dereferenceable. - fn deref_pointer_unchecked( - &self, - val: &ImmTy<'tcx, Provenance>, - layout: TyAndLayout<'tcx>, - ) -> InterpResult<'tcx, MPlaceTy<'tcx, Provenance>> { - let this = self.eval_context_ref(); - let mut mplace = this.ref_to_mplace(val)?; - - mplace.layout = layout; - mplace.align = layout.align.abi; - - Ok(mplace) + Ok(this.ptr_to_mplace(ptr, layout)) } /// Calculates the MPlaceTy given the offset and layout of an access on an operand @@ -805,7 +785,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { loop { // FIXME: We are re-getting the allocation each time around the loop. // Would be nice if we could somehow "extend" an existing AllocRange. - let alloc = this.get_ptr_alloc(ptr.offset(len, this)?, size1, Align::ONE)?.unwrap(); // not a ZST, so we will get a result + let alloc = this.get_ptr_alloc(ptr.offset(len, this)?, size1)?.unwrap(); // not a ZST, so we will get a result let byte = alloc.read_integer(alloc_range(Size::ZERO, size1))?.to_u8()?; if byte == 0 { break; @@ -845,13 +825,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { fn read_wide_str(&self, mut ptr: Pointer>) -> InterpResult<'tcx, Vec> { let this = self.eval_context_ref(); let size2 = Size::from_bytes(2); - let align2 = Align::from_bytes(2).unwrap(); + this.check_ptr_align(ptr, Align::from_bytes(2).unwrap())?; let mut wchars = Vec::new(); loop { // FIXME: We are re-getting the allocation each time around the loop. // Would be nice if we could somehow "extend" an existing AllocRange. - let alloc = this.get_ptr_alloc(ptr, size2, align2)?.unwrap(); // not a ZST, so we will get a result + let alloc = this.get_ptr_alloc(ptr, size2)?.unwrap(); // not a ZST, so we will get a result let wchar = alloc.read_integer(alloc_range(Size::ZERO, size2))?.to_u16()?; if wchar == 0 { break; @@ -887,9 +867,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Store the UTF-16 string. let size2 = Size::from_bytes(2); let this = self.eval_context_mut(); - let mut alloc = this - .get_ptr_alloc_mut(ptr, size2 * string_length, Align::from_bytes(2).unwrap())? - .unwrap(); // not a ZST, so we will get a result + this.check_ptr_align(ptr, Align::from_bytes(2).unwrap())?; + let mut alloc = this.get_ptr_alloc_mut(ptr, size2 * string_length)?.unwrap(); // not a ZST, so we will get a result for (offset, wchar) in wide_str.iter().copied().chain(iter::once(0x0000)).enumerate() { let offset = u64::try_from(offset).unwrap(); alloc.write_scalar(alloc_range(size2 * offset, size2), Scalar::from_u16(wchar))?; diff --git a/src/machine.rs b/src/machine.rs index 439cff84bd..864374bfdf 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -1288,6 +1288,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for MiriMachine<'mir, 'tcx> { // We do need to write `uninit` so that even after the call ends, the former contents of // this place cannot be observed any more. We do the write after retagging so that for // Tree Borrows, this is considered to activate the new tag. + // Conveniently this also ensures that the place actually points to suitable memory. ecx.write_uninit(&protected_place)?; // Now we throw away the protected place, ensuring its tag is never used again. Ok(()) diff --git a/src/shims/foreign_items.rs b/src/shims/foreign_items.rs index 3462f03c30..2d5df30374 100644 --- a/src/shims/foreign_items.rs +++ b/src/shims/foreign_items.rs @@ -805,14 +805,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.ptr_get_alloc_id(ptr_dest)?; this.ptr_get_alloc_id(ptr_src)?; - this.mem_copy( - ptr_src, - Align::ONE, - ptr_dest, - Align::ONE, - Size::from_bytes(n), - true, - )?; + this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?; this.write_pointer(ptr_dest, dest)?; } "strcpy" => { @@ -828,14 +821,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // reason to have `strcpy` destroy pointer provenance. // This reads at least 1 byte, so we are already enforcing that this is a valid pointer. let n = this.read_c_str(ptr_src)?.len().checked_add(1).unwrap(); - this.mem_copy( - ptr_src, - Align::ONE, - ptr_dest, - Align::ONE, - Size::from_bytes(n), - true, - )?; + this.mem_copy(ptr_src, ptr_dest, Size::from_bytes(n), true)?; this.write_pointer(ptr_dest, dest)?; } diff --git a/src/shims/unix/fs.rs b/src/shims/unix/fs.rs index 1014a61b75..062623a7f6 100644 --- a/src/shims/unix/fs.rs +++ b/src/shims/unix/fs.rs @@ -13,7 +13,7 @@ use log::trace; use rustc_data_structures::fx::FxHashMap; use rustc_middle::ty::TyCtxt; -use rustc_target::abi::{Align, Size}; +use rustc_target::abi::Size; use crate::shims::os_str::bytes_to_os_str; use crate::*; @@ -756,12 +756,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { trace!("Reading from FD {}, size {}", fd, count); // Check that the *entire* buffer is actually valid memory. - this.check_ptr_access_align( - buf, - Size::from_bytes(count), - Align::ONE, - CheckInAllocMsg::MemoryAccessTest, - )?; + this.check_ptr_access(buf, Size::from_bytes(count), CheckInAllocMsg::MemoryAccessTest)?; // We cap the number of read bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. @@ -810,12 +805,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { // Isolation check is done via `FileDescriptor` trait. // Check that the *entire* buffer is actually valid memory. - this.check_ptr_access_align( - buf, - Size::from_bytes(count), - Align::ONE, - CheckInAllocMsg::MemoryAccessTest, - )?; + this.check_ptr_access(buf, Size::from_bytes(count), CheckInAllocMsg::MemoryAccessTest)?; // We cap the number of written bytes to the largest value that we are able to fit in both the // host's and target's `isize`. This saves us from having to handle overflows later. @@ -1370,7 +1360,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { ("d_reclen", size.into()), ("d_type", file_type.into()), ], - &MPlaceTy::from_aligned_ptr(entry, dirent64_layout), + &this.ptr_to_mplace(entry, dirent64_layout), )?; let name_ptr = entry.offset(Size::from_bytes(d_name_offset), this)?; diff --git a/src/shims/unix/linux/sync.rs b/src/shims/unix/linux/sync.rs index 7d15abfbfb..ff25b8120b 100644 --- a/src/shims/unix/linux/sync.rs +++ b/src/shims/unix/linux/sync.rs @@ -34,7 +34,7 @@ pub fn futex<'tcx>( let thread = this.get_active_thread(); // This is a vararg function so we have to bring our own type for this pointer. - let addr = MPlaceTy::from_aligned_ptr(addr, this.machine.layouts.i32); + let addr = this.ptr_to_mplace(addr, this.machine.layouts.i32); let addr_usize = addr.ptr().addr().bytes(); let futex_private = this.eval_libc_i32("FUTEX_PRIVATE_FLAG"); @@ -85,11 +85,7 @@ pub fn futex<'tcx>( return Ok(()); } - // `read_timespec` will check the place when it is not null. - let timeout = this.deref_pointer_unchecked( - &this.read_immediate(&args[3])?, - this.libc_ty_layout("timespec"), - )?; + let timeout = this.deref_pointer_as(&args[3], this.libc_ty_layout("timespec"))?; let timeout_time = if this.ptr_is_null(timeout.ptr())? { None } else { diff --git a/src/shims/windows/sync.rs b/src/shims/windows/sync.rs index c8c8173aa5..2c9603097c 100644 --- a/src/shims/windows/sync.rs +++ b/src/shims/windows/sync.rs @@ -321,9 +321,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.atomic_fence(AtomicFenceOrd::SeqCst)?; let layout = this.machine.layouts.uint(size).unwrap(); - let futex_val = this - .read_scalar_atomic(&MPlaceTy::from_aligned_ptr(ptr, layout), AtomicReadOrd::Relaxed)?; - let compare_val = this.read_scalar(&MPlaceTy::from_aligned_ptr(compare, layout))?; + let futex_val = + this.read_scalar_atomic(&this.ptr_to_mplace(ptr, layout), AtomicReadOrd::Relaxed)?; + let compare_val = this.read_scalar(&this.ptr_to_mplace(compare, layout))?; if futex_val == compare_val { // If the values are the same, we have to block. diff --git a/src/shims/x86/sse3.rs b/src/shims/x86/sse3.rs index a41de5dbf7..246e9e9c6c 100644 --- a/src/shims/x86/sse3.rs +++ b/src/shims/x86/sse3.rs @@ -1,6 +1,5 @@ use rustc_middle::mir; use rustc_span::Symbol; -use rustc_target::abi::Align; use rustc_target::spec::abi::Abi; use super::horizontal_bin_op; @@ -74,14 +73,7 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>: let src_ptr = this.read_pointer(src_ptr)?; let dest = dest.force_mplace(this)?; - this.mem_copy( - src_ptr, - Align::ONE, - dest.ptr(), - Align::ONE, - dest.layout.size, - /*nonoverlapping*/ true, - )?; + this.mem_copy(src_ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?; } _ => return Ok(EmulateForeignItemResult::NotSupported), } diff --git a/tests/compiletest.rs b/tests/compiletest.rs index c2dccf8137..dbf559631e 100644 --- a/tests/compiletest.rs +++ b/tests/compiletest.rs @@ -181,6 +181,7 @@ regexes! { r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX", // erase specific alignments "alignment [0-9]+" => "alignment ALIGN", + "[0-9]+ byte alignment but found [0-9]+" => "ALIGN byte alignment but found ALIGN", // erase thread caller ids r"call [0-9]+" => "call ID", // erase platform module paths diff --git a/tests/fail-dep/shims/mmap_use_after_munmap.stderr b/tests/fail-dep/shims/mmap_use_after_munmap.stderr index 44e122330b..35d2697283 100644 --- a/tests/fail-dep/shims/mmap_use_after_munmap.stderr +++ b/tests/fail-dep/shims/mmap_use_after_munmap.stderr @@ -13,11 +13,11 @@ LL | libc::munmap(ptr, 4096); = note: BACKTRACE: = note: inside `main` at $DIR/mmap_use_after_munmap.rs:LL:CC -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/mmap_use_after_munmap.rs:LL:CC | LL | let _x = *(ptr as *mut u8); - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/alloc/reallocate-change-alloc.stderr b/tests/fail/alloc/reallocate-change-alloc.stderr index ff4cb39915..d4e907bd06 100644 --- a/tests/fail/alloc/reallocate-change-alloc.stderr +++ b/tests/fail/alloc/reallocate-change-alloc.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/reallocate-change-alloc.rs:LL:CC | LL | let _z = *x; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/concurrency/thread_local_static_dealloc.stderr b/tests/fail/concurrency/thread_local_static_dealloc.stderr index 0cb8aa2900..7069e8cccf 100644 --- a/tests/fail/concurrency/thread_local_static_dealloc.stderr +++ b/tests/fail/concurrency/thread_local_static_dealloc.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/thread_local_static_dealloc.rs:LL:CC | LL | let _val = *dangling_ptr.0; - | ^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/const-ub-checks.stderr b/tests/fail/const-ub-checks.stderr index d2b9018cd4..29acc642c1 100644 --- a/tests/fail/const-ub-checks.stderr +++ b/tests/fail/const-ub-checks.stderr @@ -2,7 +2,7 @@ error[E0080]: evaluation of constant value failed --> $DIR/const-ub-checks.rs:LL:CC | LL | ptr.read(); - | ^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required note: erroneous constant encountered --> $DIR/const-ub-checks.rs:LL:CC diff --git a/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs b/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs deleted file mode 100644 index 49f3ae306a..0000000000 --- a/tests/fail/dangling_pointers/dangling_pointer_addr_of.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Make sure we find these even with many checks disabled. -//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation -use std::ptr; - -fn main() { - let p = { - let b = Box::new(42); - &*b as *const i32 - }; - let x = unsafe { ptr::addr_of!(*p) }; //~ ERROR: has been freed - panic!("this should never print: {:?}", x); -} diff --git a/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr b/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr deleted file mode 100644 index 6a3efbdd3d..0000000000 --- a/tests/fail/dangling_pointers/dangling_pointer_addr_of.stderr +++ /dev/null @@ -1,26 +0,0 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling - --> $DIR/dangling_pointer_addr_of.rs:LL:CC - | -LL | let x = unsafe { ptr::addr_of!(*p) }; - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/dangling_pointer_addr_of.rs:LL:CC - | -LL | let b = Box::new(42); - | ^^^^^^^^^^^^ -help: ALLOC was deallocated here: - --> $DIR/dangling_pointer_addr_of.rs:LL:CC - | -LL | }; - | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: this error originates in the macro `ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - diff --git a/tests/fail/dangling_pointers/dangling_pointer_deref.stderr b/tests/fail/dangling_pointers/dangling_pointer_deref.stderr index fad4b4be28..33d640759f 100644 --- a/tests/fail/dangling_pointers/dangling_pointer_deref.stderr +++ b/tests/fail/dangling_pointers/dangling_pointer_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_pointer_deref.rs:LL:CC | LL | let x = unsafe { *p }; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs b/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs index 4c64124395..22a5ce8ea7 100644 --- a/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs +++ b/tests/fail/dangling_pointers/dangling_pointer_project_underscore.rs @@ -4,10 +4,9 @@ fn main() { let p = { let b = Box::new(42); - &*b as *const i32 + &*b as *const i32 as *const (u8, u8, u8, u8) }; unsafe { - let _ = *p; //~ ERROR: has been freed + let _ = (*p).1; //~ ERROR: out-of-bounds pointer arithmetic } - panic!("this should never print"); } diff --git a/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr b/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr index 1de6465802..20f3a25a0b 100644 --- a/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr +++ b/tests/fail/dangling_pointers/dangling_pointer_project_underscore.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: out-of-bounds pointer arithmetic: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_pointer_project_underscore.rs:LL:CC | -LL | let _ = *p; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +LL | let _ = (*p).1; + | ^^^^^^ out-of-bounds pointer arithmetic: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/dangling_primitive.stderr b/tests/fail/dangling_pointers/dangling_primitive.stderr index bdc9c31db4..c2a73bfbcb 100644 --- a/tests/fail/dangling_pointers/dangling_primitive.stderr +++ b/tests/fail/dangling_pointers/dangling_primitive.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_primitive.rs:LL:CC | LL | dbg!(*ptr); - | ^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/dangling_zst_deref.stderr b/tests/fail/dangling_pointers/dangling_zst_deref.stderr index bf6ee775e9..d8cb691e55 100644 --- a/tests/fail/dangling_pointers/dangling_zst_deref.stderr +++ b/tests/fail/dangling_pointers/dangling_zst_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dangling_zst_deref.rs:LL:CC | LL | let _x = unsafe { *p }; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/deref-invalid-ptr.stderr b/tests/fail/dangling_pointers/deref-invalid-ptr.stderr index 3e2c3903b7..f11863b506 100644 --- a/tests/fail/dangling_pointers/deref-invalid-ptr.stderr +++ b/tests/fail/dangling_pointers/deref-invalid-ptr.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: 0x10[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: out-of-bounds pointer use: 0x10[noalloc] is a dangling pointer (it has no provenance) --> $DIR/deref-invalid-ptr.rs:LL:CC | LL | let _y = unsafe { &*x as *const u32 }; - | ^^^ dereferencing pointer failed: 0x10[noalloc] is a dangling pointer (it has no provenance) + | ^^^ out-of-bounds pointer use: 0x10[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/deref-partially-dangling.rs b/tests/fail/dangling_pointers/deref-partially-dangling.rs deleted file mode 100644 index 27040c26dc..0000000000 --- a/tests/fail/dangling_pointers/deref-partially-dangling.rs +++ /dev/null @@ -1,8 +0,0 @@ -// Deref a raw ptr to access a field of a large struct, where the field -// is allocated but not the entire struct is. -fn main() { - let x = (1, 13); - let xptr = &x as *const _ as *const (i32, i32, i32); - let val = unsafe { (*xptr).1 }; //~ ERROR: pointer to 12 bytes starting at offset 0 is out-of-bounds - assert_eq!(val, 13); -} diff --git a/tests/fail/dangling_pointers/deref-partially-dangling.stderr b/tests/fail/dangling_pointers/deref-partially-dangling.stderr deleted file mode 100644 index 92b1fcb114..0000000000 --- a/tests/fail/dangling_pointers/deref-partially-dangling.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 8, so pointer to 12 bytes starting at offset 0 is out-of-bounds - --> $DIR/deref-partially-dangling.rs:LL:CC - | -LL | let val = unsafe { (*xptr).1 }; - | ^^^^^^^^^ dereferencing pointer failed: ALLOC has size 8, so pointer to 12 bytes starting at offset 0 is out-of-bounds - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/deref-partially-dangling.rs:LL:CC - | -LL | let x = (1, 13); - | ^ - = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/deref-partially-dangling.rs:LL:CC - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - diff --git a/tests/fail/dangling_pointers/deref_dangling_box.rs b/tests/fail/dangling_pointers/deref_dangling_box.rs new file mode 100644 index 0000000000..d2823672ad --- /dev/null +++ b/tests/fail/dangling_pointers/deref_dangling_box.rs @@ -0,0 +1,16 @@ +// Should be caught even without retagging +//@compile-flags: -Zmiri-disable-stacked-borrows +#![feature(strict_provenance)] +use std::ptr::{self, addr_of_mut}; + +// Deref'ing a dangling raw pointer is fine, but for a dangling box it is not. +// We do this behind a pointer indirection to potentially fool validity checking. +// (This test relies on the `deref_copy` pass that lowers `**ptr` to materialize the intermediate pointer.) + +fn main() { + let mut inner = ptr::invalid::(24); + let outer = addr_of_mut!(inner).cast::>(); + // Now `outer` is a pointer to a dangling reference. + // Deref'ing that should be UB. + let _val = unsafe { addr_of_mut!(**outer) }; //~ERROR: dangling box +} diff --git a/tests/fail/dangling_pointers/deref_dangling_box.stderr b/tests/fail/dangling_pointers/deref_dangling_box.stderr new file mode 100644 index 0000000000..64d6d36c2c --- /dev/null +++ b/tests/fail/dangling_pointers/deref_dangling_box.stderr @@ -0,0 +1,16 @@ +error: Undefined Behavior: constructing invalid value: encountered a dangling box (0x18[noalloc] has no provenance) + --> $DIR/deref_dangling_box.rs:LL:CC + | +LL | let _val = unsafe { addr_of_mut!(**outer) }; + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling box (0x18[noalloc] has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: this error originates in the macro `addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/fail/dangling_pointers/deref_dangling_ref.rs b/tests/fail/dangling_pointers/deref_dangling_ref.rs new file mode 100644 index 0000000000..b62e041d70 --- /dev/null +++ b/tests/fail/dangling_pointers/deref_dangling_ref.rs @@ -0,0 +1,16 @@ +// Should be caught even without retagging +//@compile-flags: -Zmiri-disable-stacked-borrows +#![feature(strict_provenance)] +use std::ptr::{self, addr_of_mut}; + +// Deref'ing a dangling raw pointer is fine, but for a dangling reference it is not. +// We do this behind a pointer indirection to potentially fool validity checking. +// (This test relies on the `deref_copy` pass that lowers `**ptr` to materialize the intermediate pointer.) + +fn main() { + let mut inner = ptr::invalid::(24); + let outer = addr_of_mut!(inner).cast::<&'static mut i32>(); + // Now `outer` is a pointer to a dangling reference. + // Deref'ing that should be UB. + let _val = unsafe { addr_of_mut!(**outer) }; //~ERROR: dangling reference +} diff --git a/tests/fail/dangling_pointers/deref_dangling_ref.stderr b/tests/fail/dangling_pointers/deref_dangling_ref.stderr new file mode 100644 index 0000000000..244e3f4b65 --- /dev/null +++ b/tests/fail/dangling_pointers/deref_dangling_ref.stderr @@ -0,0 +1,16 @@ +error: Undefined Behavior: constructing invalid value: encountered a dangling reference (0x18[noalloc] has no provenance) + --> $DIR/deref_dangling_ref.rs:LL:CC + | +LL | let _val = unsafe { addr_of_mut!(**outer) }; + | ^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered a dangling reference (0x18[noalloc] has no provenance) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: this error originates in the macro `addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/fail/dangling_pointers/dyn_size.rs b/tests/fail/dangling_pointers/dyn_size.rs index 87ca8a6077..fa01bbc19c 100644 --- a/tests/fail/dangling_pointers/dyn_size.rs +++ b/tests/fail/dangling_pointers/dyn_size.rs @@ -1,13 +1,13 @@ -// should find the bug even without these -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows +// should find the bug even without retagging +//@compile-flags: -Zmiri-disable-stacked-borrows struct SliceWithHead(u8, [u8]); fn main() { let buf = [0u32; 1]; // We craft a wide pointer `*const SliceWithHead` such that the unsized tail is only partially allocated. - // That should be UB, as the reference is not fully dereferencable. + // That should lead to UB, as the reference is not fully dereferenceable. let ptr: *const SliceWithHead = unsafe { std::mem::transmute((&buf, 4usize)) }; // Re-borrow that. This should be UB. - let _ptr = unsafe { &*ptr }; //~ ERROR: pointer to 5 bytes starting at offset 0 is out-of-bounds + let _ptr = unsafe { &*ptr }; //~ ERROR: encountered a dangling reference (going beyond the bounds of its allocation) } diff --git a/tests/fail/dangling_pointers/dyn_size.stderr b/tests/fail/dangling_pointers/dyn_size.stderr index 95a50bc875..4d45630e1b 100644 --- a/tests/fail/dangling_pointers/dyn_size.stderr +++ b/tests/fail/dangling_pointers/dyn_size.stderr @@ -1,17 +1,12 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 4, so pointer to 5 bytes starting at offset 0 is out-of-bounds +error: Undefined Behavior: constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) --> $DIR/dyn_size.rs:LL:CC | LL | let _ptr = unsafe { &*ptr }; - | ^^^^^ dereferencing pointer failed: ALLOC has size 4, so pointer to 5 bytes starting at offset 0 is out-of-bounds + | ^^^^^ constructing invalid value: encountered a dangling reference (going beyond the bounds of its allocation) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information -help: ALLOC was allocated here: - --> $DIR/dyn_size.rs:LL:CC - | -LL | let buf = [0u32; 1]; - | ^^^ - = note: BACKTRACE (of the first span): + = note: BACKTRACE: = note: inside `main` at $DIR/dyn_size.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr b/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr index 3e492a170c..895d4c7fce 100644 --- a/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr +++ b/tests/fail/dangling_pointers/maybe_null_pointer_deref_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds --> $DIR/maybe_null_pointer_deref_zst.rs:LL:CC | LL | let _x: () = unsafe { *ptr }; - | ^^^^ dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds + | ^^^^ memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr b/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr index c41c20aaf4..6cc05758b7 100644 --- a/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr +++ b/tests/fail/dangling_pointers/maybe_null_pointer_write_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds --> $DIR/maybe_null_pointer_write_zst.rs:LL:CC | LL | unsafe { *ptr = zst_val }; - | ^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds + | ^^^^^^^^^^^^^^ memory access failed: ALLOC has size 1, so pointer at offset -2048 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/null_pointer_deref.stderr b/tests/fail/dangling_pointers/null_pointer_deref.stderr index 64dcaa4548..727c724552 100644 --- a/tests/fail/dangling_pointers/null_pointer_deref.stderr +++ b/tests/fail/dangling_pointers/null_pointer_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_deref.rs:LL:CC | LL | let x: i32 = unsafe { *std::ptr::null() }; - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/null_pointer_deref_zst.rs b/tests/fail/dangling_pointers/null_pointer_deref_zst.rs index 4cb805db09..f8af43ff35 100644 --- a/tests/fail/dangling_pointers/null_pointer_deref_zst.rs +++ b/tests/fail/dangling_pointers/null_pointer_deref_zst.rs @@ -1,5 +1,5 @@ #[allow(deref_nullptr)] fn main() { - let x: () = unsafe { *std::ptr::null() }; //~ ERROR: dereferencing pointer failed: null pointer is a dangling pointer + let x: () = unsafe { *std::ptr::null() }; //~ ERROR: memory access failed: null pointer is a dangling pointer panic!("this should never print: {:?}", x); } diff --git a/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr b/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr index 301578a4f5..9f93a0e18a 100644 --- a/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr +++ b/tests/fail/dangling_pointers/null_pointer_deref_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_deref_zst.rs:LL:CC | LL | let x: () = unsafe { *std::ptr::null() }; - | ^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/null_pointer_write.stderr b/tests/fail/dangling_pointers/null_pointer_write.stderr index 0e5858a96f..6974b99772 100644 --- a/tests/fail/dangling_pointers/null_pointer_write.stderr +++ b/tests/fail/dangling_pointers/null_pointer_write.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_write.rs:LL:CC | LL | unsafe { *std::ptr::null_mut() = 0i32 }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/null_pointer_write_zst.rs b/tests/fail/dangling_pointers/null_pointer_write_zst.rs index ec34c631a4..edd6c8fadc 100644 --- a/tests/fail/dangling_pointers/null_pointer_write_zst.rs +++ b/tests/fail/dangling_pointers/null_pointer_write_zst.rs @@ -4,5 +4,5 @@ fn main() { // Also not assigning directly as that's array initialization, not assignment. let zst_val = [1u8; 0]; unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; - //~^ERROR: dereferencing pointer failed: null pointer is a dangling pointer + //~^ERROR: memory access failed: null pointer is a dangling pointer } diff --git a/tests/fail/dangling_pointers/null_pointer_write_zst.stderr b/tests/fail/dangling_pointers/null_pointer_write_zst.stderr index a4e0ebe38f..2953d85c25 100644 --- a/tests/fail/dangling_pointers/null_pointer_write_zst.stderr +++ b/tests/fail/dangling_pointers/null_pointer_write_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: null pointer is a dangling pointer (it has no provenance) --> $DIR/null_pointer_write_zst.rs:LL:CC | LL | unsafe { std::ptr::null_mut::<[u8; 0]>().write(zst_val) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: null pointer is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: null pointer is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/out_of_bounds_project.rs b/tests/fail/dangling_pointers/out_of_bounds_project.rs new file mode 100644 index 0000000000..b596ba428a --- /dev/null +++ b/tests/fail/dangling_pointers/out_of_bounds_project.rs @@ -0,0 +1,12 @@ +// Make sure we find these even with many checks disabled. +//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation +use std::ptr::addr_of; + +fn main() { + let v = 0u32; + let ptr = addr_of!(v).cast::<(u32, u32, u32)>(); + unsafe { + let _field = addr_of!((*ptr).1); // still just in-bounds + let _field = addr_of!((*ptr).2); //~ ERROR: out-of-bounds pointer arithmetic + } +} diff --git a/tests/fail/dangling_pointers/out_of_bounds_project.stderr b/tests/fail/dangling_pointers/out_of_bounds_project.stderr new file mode 100644 index 0000000000..1c10599101 --- /dev/null +++ b/tests/fail/dangling_pointers/out_of_bounds_project.stderr @@ -0,0 +1,21 @@ +error: Undefined Behavior: out-of-bounds pointer arithmetic: ALLOC has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + --> $DIR/out_of_bounds_project.rs:LL:CC + | +LL | let _field = addr_of!((*ptr).2); + | ^^^^^^^^^^^^^^^^^^ out-of-bounds pointer arithmetic: ALLOC has size 4, so pointer to 8 bytes starting at offset 0 is out-of-bounds + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information +help: ALLOC was allocated here: + --> $DIR/out_of_bounds_project.rs:LL:CC + | +LL | let v = 0u32; + | ^ + = note: BACKTRACE (of the first span): + = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: this error originates in the macro `addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/fail/dangling_pointers/out_of_bounds_read.rs b/tests/fail/dangling_pointers/out_of_bounds_read.rs new file mode 100644 index 0000000000..f6b8a1ad55 --- /dev/null +++ b/tests/fail/dangling_pointers/out_of_bounds_read.rs @@ -0,0 +1,8 @@ +#![feature(pointer_byte_offsets)] + +fn main() { + let v: Vec = vec![1, 2]; + // This read is also misaligned. We make sure that the OOB message has priority. + let x = unsafe { *v.as_ptr().wrapping_byte_add(5) }; //~ ERROR: out-of-bounds + panic!("this should never print: {}", x); +} diff --git a/tests/fail/dangling_pointers/out_of_bounds_read1.stderr b/tests/fail/dangling_pointers/out_of_bounds_read.stderr similarity index 50% rename from tests/fail/dangling_pointers/out_of_bounds_read1.stderr rename to tests/fail/dangling_pointers/out_of_bounds_read.stderr index 7d2aed371b..38d691f4c0 100644 --- a/tests/fail/dangling_pointers/out_of_bounds_read1.stderr +++ b/tests/fail/dangling_pointers/out_of_bounds_read.stderr @@ -1,18 +1,18 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds - --> $DIR/out_of_bounds_read1.rs:LL:CC +error: Undefined Behavior: memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds + --> $DIR/out_of_bounds_read.rs:LL:CC | -LL | let x = unsafe { *v.as_ptr().wrapping_offset(5) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds +LL | let x = unsafe { *v.as_ptr().wrapping_byte_add(5) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information help: ALLOC was allocated here: - --> $DIR/out_of_bounds_read1.rs:LL:CC + --> $DIR/out_of_bounds_read.rs:LL:CC | -LL | let v: Vec = vec![1, 2]; - | ^^^^^^^^^^ +LL | let v: Vec = vec![1, 2]; + | ^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/out_of_bounds_read1.rs:LL:CC + = note: inside `main` at $DIR/out_of_bounds_read.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/dangling_pointers/out_of_bounds_read1.rs b/tests/fail/dangling_pointers/out_of_bounds_read1.rs deleted file mode 100644 index 58a64eecac..0000000000 --- a/tests/fail/dangling_pointers/out_of_bounds_read1.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let v: Vec = vec![1, 2]; - let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR: out-of-bounds - panic!("this should never print: {}", x); -} diff --git a/tests/fail/dangling_pointers/out_of_bounds_read2.rs b/tests/fail/dangling_pointers/out_of_bounds_read2.rs deleted file mode 100644 index 58a64eecac..0000000000 --- a/tests/fail/dangling_pointers/out_of_bounds_read2.rs +++ /dev/null @@ -1,5 +0,0 @@ -fn main() { - let v: Vec = vec![1, 2]; - let x = unsafe { *v.as_ptr().wrapping_offset(5) }; //~ ERROR: out-of-bounds - panic!("this should never print: {}", x); -} diff --git a/tests/fail/dangling_pointers/out_of_bounds_write.rs b/tests/fail/dangling_pointers/out_of_bounds_write.rs new file mode 100644 index 0000000000..4ead91744c --- /dev/null +++ b/tests/fail/dangling_pointers/out_of_bounds_write.rs @@ -0,0 +1,7 @@ +#![feature(pointer_byte_offsets)] + +fn main() { + let mut v: Vec = vec![1, 2]; + // This read is also misaligned. We make sure that the OOB message has priority. + unsafe { *v.as_mut_ptr().wrapping_byte_add(5) = 0 }; //~ ERROR: out-of-bounds +} diff --git a/tests/fail/dangling_pointers/out_of_bounds_read2.stderr b/tests/fail/dangling_pointers/out_of_bounds_write.stderr similarity index 50% rename from tests/fail/dangling_pointers/out_of_bounds_read2.stderr rename to tests/fail/dangling_pointers/out_of_bounds_write.stderr index 69a8498f09..9669614d47 100644 --- a/tests/fail/dangling_pointers/out_of_bounds_read2.stderr +++ b/tests/fail/dangling_pointers/out_of_bounds_write.stderr @@ -1,18 +1,18 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds - --> $DIR/out_of_bounds_read2.rs:LL:CC +error: Undefined Behavior: memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds + --> $DIR/out_of_bounds_write.rs:LL:CC | -LL | let x = unsafe { *v.as_ptr().wrapping_offset(5) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 2, so pointer to 1 byte starting at offset 5 is out-of-bounds +LL | unsafe { *v.as_mut_ptr().wrapping_byte_add(5) = 0 }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 4, so pointer to 2 bytes starting at offset 5 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information help: ALLOC was allocated here: - --> $DIR/out_of_bounds_read2.rs:LL:CC + --> $DIR/out_of_bounds_write.rs:LL:CC | -LL | let v: Vec = vec![1, 2]; - | ^^^^^^^^^^ +LL | let mut v: Vec = vec![1, 2]; + | ^^^^^^^^^^ = note: BACKTRACE (of the first span): - = note: inside `main` at $DIR/out_of_bounds_read2.rs:LL:CC + = note: inside `main` at $DIR/out_of_bounds_write.rs:LL:CC = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/dangling_pointers/stack_temporary.stderr b/tests/fail/dangling_pointers/stack_temporary.stderr index 4d2dfe28ae..28a9207cff 100644 --- a/tests/fail/dangling_pointers/stack_temporary.stderr +++ b/tests/fail/dangling_pointers/stack_temporary.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/stack_temporary.rs:LL:CC | LL | let val = *x; - | ^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/tests/fail/dangling_pointers/storage_dead_dangling.stderr index 6c41add60e..9b47655a04 100644 --- a/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: out-of-bounds pointer use: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/storage_dead_dangling.rs:LL:CC | LL | let _ = unsafe { &mut *(LEAK as *mut i32) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/dangling_pointers/wild_pointer_deref.stderr b/tests/fail/dangling_pointers/wild_pointer_deref.stderr index 658fb22817..802995aea5 100644 --- a/tests/fail/dangling_pointers/wild_pointer_deref.stderr +++ b/tests/fail/dangling_pointers/wild_pointer_deref.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) --> $DIR/wild_pointer_deref.rs:LL:CC | LL | let x = unsafe { *p }; - | ^^ dereferencing pointer failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) + | ^^ memory access failed: 0x2c[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/data_race/dealloc_read_race2.stderr b/tests/fail/data_race/dealloc_read_race2.stderr index 810e48d59c..792faf8f5d 100644 --- a/tests/fail/data_race/dealloc_read_race2.stderr +++ b/tests/fail/data_race/dealloc_read_race2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dealloc_read_race2.rs:LL:CC | LL | *ptr.0 - | ^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/data_race/dealloc_write_race2.stderr b/tests/fail/data_race/dealloc_write_race2.stderr index 7d672cd4d6..64f654402d 100644 --- a/tests/fail/data_race/dealloc_write_race2.stderr +++ b/tests/fail/data_race/dealloc_write_race2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/dealloc_write_race2.rs:LL:CC | LL | *ptr.0 = 2; - | ^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/environ-gets-deallocated.stderr b/tests/fail/environ-gets-deallocated.stderr index 6332846d5d..dd7420906d 100644 --- a/tests/fail/environ-gets-deallocated.stderr +++ b/tests/fail/environ-gets-deallocated.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/environ-gets-deallocated.rs:LL:CC | LL | let _y = unsafe { *pointer }; - | ^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/function_pointers/deref_fn_ptr.rs b/tests/fail/function_pointers/deref_fn_ptr.rs index f071b63902..3510f41361 100644 --- a/tests/fail/function_pointers/deref_fn_ptr.rs +++ b/tests/fail/function_pointers/deref_fn_ptr.rs @@ -2,7 +2,7 @@ fn f() {} fn main() { let x: u8 = unsafe { - *std::mem::transmute::(f) //~ ERROR: out-of-bounds + *std::mem::transmute::(f) //~ ERROR: contains a function }; panic!("this should never print: {}", x); } diff --git a/tests/fail/function_pointers/deref_fn_ptr.stderr b/tests/fail/function_pointers/deref_fn_ptr.stderr index 7ce0b08695..954bb8721e 100644 --- a/tests/fail/function_pointers/deref_fn_ptr.stderr +++ b/tests/fail/function_pointers/deref_fn_ptr.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds +error: Undefined Behavior: accessing ALLOC which contains a function --> $DIR/deref_fn_ptr.rs:LL:CC | LL | *std::mem::transmute::(f) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing ALLOC which contains a function | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/generator-pinned-moved.stderr b/tests/fail/generator-pinned-moved.stderr index 4cb8450c6d..8ad0ce8cc3 100644 --- a/tests/fail/generator-pinned-moved.stderr +++ b/tests/fail/generator-pinned-moved.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/generator-pinned-moved.rs:LL:CC | LL | *num += 1; - | ^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/intrinsics/simd-gather.stderr b/tests/fail/intrinsics/simd-gather.stderr index f82b30a963..f3bd275b02 100644 --- a/tests/fail/intrinsics/simd-gather.stderr +++ b/tests/fail/intrinsics/simd-gather.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds --> $DIR/simd-gather.rs:LL:CC | LL | let _result = Simd::gather_select_unchecked(&vec, Mask::splat(true), idxs, Simd::splat(0)); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/intrinsics/simd-scatter.stderr b/tests/fail/intrinsics/simd-scatter.stderr index 5beee034db..1720a24aa1 100644 --- a/tests/fail/intrinsics/simd-scatter.stderr +++ b/tests/fail/intrinsics/simd-scatter.stderr @@ -1,4 +1,4 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds --> $DIR/simd-scatter.rs:LL:CC | LL | / Simd::from_array([-27, 82, -41, 124]).scatter_select_unchecked( @@ -7,7 +7,7 @@ LL | | &mut vec, LL | | Mask::splat(true), LL | | idxs, LL | | ); - | |_________^ dereferencing pointer failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds + | |_________^ memory access failed: ALLOC has size 9, so pointer to 1 byte starting at offset 9 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/provenance/pointer_partial_overwrite.stderr b/tests/fail/provenance/pointer_partial_overwrite.stderr index 06e5ede8c7..8fafc7e82c 100644 --- a/tests/fail/provenance/pointer_partial_overwrite.stderr +++ b/tests/fail/provenance/pointer_partial_overwrite.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/pointer_partial_overwrite.rs:LL:CC | LL | let x = *p; - | ^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/provenance/provenance_transmute.rs b/tests/fail/provenance/provenance_transmute.rs index abcfc060e5..bc5dd53dcf 100644 --- a/tests/fail/provenance/provenance_transmute.rs +++ b/tests/fail/provenance/provenance_transmute.rs @@ -13,7 +13,7 @@ unsafe fn deref(left: *const u8, right: *const u8) { // The compiler is allowed to replace `left_int` by `right_int` here... let left_ptr: *const u8 = mem::transmute(left_int); // ...which however means here it could be dereferencing the wrong pointer. - let _val = *left_ptr; //~ERROR: dereferencing pointer failed + let _val = *left_ptr; //~ERROR: dangling pointer } } diff --git a/tests/fail/provenance/provenance_transmute.stderr b/tests/fail/provenance/provenance_transmute.stderr index 042d8cd4af..319517d062 100644 --- a/tests/fail/provenance/provenance_transmute.stderr +++ b/tests/fail/provenance/provenance_transmute.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/provenance_transmute.rs:LL:CC | LL | let _val = *left_ptr; - | ^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/provenance/ptr_int_unexposed.stderr b/tests/fail/provenance/ptr_int_unexposed.stderr index 4ad885ddab..9ebabfb129 100644 --- a/tests/fail/provenance/ptr_int_unexposed.stderr +++ b/tests/fail/provenance/ptr_int_unexposed.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/ptr_int_unexposed.rs:LL:CC | LL | assert_eq!(unsafe { *ptr }, 3); - | ^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/provenance/ptr_invalid.stderr b/tests/fail/provenance/ptr_invalid.stderr index ef9dcad97c..50ceae7cfd 100644 --- a/tests/fail/provenance/ptr_invalid.stderr +++ b/tests/fail/provenance/ptr_invalid.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/ptr_invalid.rs:LL:CC | LL | let _val = unsafe { *xptr_invalid }; - | ^^^^^^^^^^^^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^^^^^^^^^^^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/rc_as_ptr.stderr b/tests/fail/rc_as_ptr.stderr index 460ed97713..eb522b2bc0 100644 --- a/tests/fail/rc_as_ptr.stderr +++ b/tests/fail/rc_as_ptr.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: out-of-bounds pointer use: ALLOC has been freed, so this pointer is dangling --> $DIR/rc_as_ptr.rs:LL:CC | LL | assert_eq!(42, **unsafe { &*Weak::as_ptr(&weak) }); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ out-of-bounds pointer use: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/reading_half_a_pointer.stderr b/tests/fail/reading_half_a_pointer.stderr index 61a7161a98..df4adb5ead 100644 --- a/tests/fail/reading_half_a_pointer.stderr +++ b/tests/fail/reading_half_a_pointer.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) +error: Undefined Behavior: memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) --> $DIR/reading_half_a_pointer.rs:LL:CC | LL | let _val = *x; - | ^^ dereferencing pointer failed: $HEX[noalloc] is a dangling pointer (it has no provenance) + | ^^ memory access failed: $HEX[noalloc] is a dangling pointer (it has no provenance) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/alignment.stderr b/tests/fail/unaligned_pointers/alignment.stderr index bbebe3b89f..5fdec1dc74 100644 --- a/tests/fail/unaligned_pointers/alignment.stderr +++ b/tests/fail/unaligned_pointers/alignment.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/alignment.rs:LL:CC | LL | *(x_ptr as *mut u32) = 42; *(x_ptr.add(1) as *mut u32) = 42; - | ^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/drop_in_place.rs b/tests/fail/unaligned_pointers/drop_in_place.rs index d8cab68ac5..d71d5954a4 100644 --- a/tests/fail/unaligned_pointers/drop_in_place.rs +++ b/tests/fail/unaligned_pointers/drop_in_place.rs @@ -13,7 +13,7 @@ struct PartialDrop { b: u8, } -//@error-in-other-file: /alignment 2 is required/ +//@error-in-other-file: /required 2 byte alignment/ fn main() { unsafe { // Create an unaligned pointer diff --git a/tests/fail/unaligned_pointers/drop_in_place.stderr b/tests/fail/unaligned_pointers/drop_in_place.stderr index ef20b43c11..db35a20ee2 100644 --- a/tests/fail/unaligned_pointers/drop_in_place.stderr +++ b/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> RUSTLIB/core/src/ptr/mod.rs:LL:CC | LL | pub unsafe fn drop_in_place(to_drop: *mut T) { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/dyn_alignment.stderr b/tests/fail/unaligned_pointers/dyn_alignment.stderr index 503721b955..cfb43ae891 100644 --- a/tests/fail/unaligned_pointers/dyn_alignment.stderr +++ b/tests/fail/unaligned_pointers/dyn_alignment.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required 256 byte alignment but found $ALIGN) +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> $DIR/dyn_alignment.rs:LL:CC | LL | let _ptr = &*ptr; - | ^^^^^ constructing invalid value: encountered an unaligned reference (required 256 byte alignment but found $ALIGN) + | ^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs index fa1812adc2..114ab5479b 100644 --- a/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs +++ b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.rs @@ -8,7 +8,7 @@ pub struct S { } unsafe fn foo(x: *const S) -> u8 { - unsafe { (*x).x } //~ERROR: accessing memory with alignment 1, but alignment 4 is required + unsafe { (*x).x } //~ERROR: based on pointer with alignment 1, but alignment 4 is required } fn main() { diff --git a/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr index 0f030a6e27..2ffbc2a434 100644 --- a/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr +++ b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/field_requires_parent_struct_alignment.rs:LL:CC | LL | unsafe { (*x).x } - | ^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs new file mode 100644 index 0000000000..8459c64ed2 --- /dev/null +++ b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.rs @@ -0,0 +1,30 @@ +/// This tests that when a field sits at a well-aligned offset, accessing the field +/// requires high alignment even if the field type has lower alignment requirements. + +#[repr(C, align(16))] +#[derive(Default, Copy, Clone)] +pub struct Aligned { + _pad: [u8; 11], + packed: Packed, +} +#[repr(packed)] +#[derive(Default, Copy, Clone)] +pub struct Packed { + _pad: [u8; 5], + x: u8, +} + +unsafe fn foo(x: *const Aligned) -> u8 { + unsafe { (*x).packed.x } //~ERROR: based on pointer with alignment 1, but alignment 16 is required +} + +fn main() { + unsafe { + let mem = [Aligned::default(); 16]; + let odd_ptr = std::ptr::addr_of!(mem).cast::().add(1); + // `odd_ptr` is now not aligned enough for `Aligned`. + // If accessing the nested field `packed.x` can exploit that it is at offset 16 + // in a 16-aligned struct, this has to be UB. + foo(odd_ptr.cast()); + } +} diff --git a/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr new file mode 100644 index 0000000000..6d96c62545 --- /dev/null +++ b/tests/fail/unaligned_pointers/field_requires_parent_struct_alignment2.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required + --> $DIR/field_requires_parent_struct_alignment2.rs:LL:CC + | +LL | unsafe { (*x).packed.x } + | ^^^^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `foo` at $DIR/field_requires_parent_struct_alignment2.rs:LL:CC +note: inside `main` + --> $DIR/field_requires_parent_struct_alignment2.rs:LL:CC + | +LL | foo(odd_ptr.cast()); + | ^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs b/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs index ed43e55250..11f6383912 100644 --- a/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs +++ b/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs @@ -12,6 +12,6 @@ fn main() { // Manually make sure the pointer is properly aligned. let base_addr_aligned = if base_addr % 2 == 0 { base_addr } else { base_addr + 1 }; let u16_ptr = base_addr_aligned as *mut u16; - unsafe { *u16_ptr = 2 }; //~ERROR: memory with alignment 1, but alignment 2 is required + unsafe { *u16_ptr = 2 }; //~ERROR: with alignment 1, but alignment 2 is required println!("{:?}", x); } diff --git a/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr b/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr index 392495a386..9342b26999 100644 --- a/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr +++ b/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/intptrcast_alignment_check.rs:LL:CC | LL | unsafe { *u16_ptr = 2 }; - | ^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^^^^^^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this usually indicates that your program performed an invalid operation and caused Undefined Behavior = help: but due to `-Zmiri-symbolic-alignment-check`, alignment errors can also be false positives diff --git a/tests/fail/unaligned_pointers/reference_to_packed.rs b/tests/fail/unaligned_pointers/reference_to_packed.rs index 4a8cf405ae..b9d29d775a 100644 --- a/tests/fail/unaligned_pointers/reference_to_packed.rs +++ b/tests/fail/unaligned_pointers/reference_to_packed.rs @@ -1,5 +1,5 @@ -// This should fail even without validation/SB -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no +// This should fail even without SB +//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no #![allow(dead_code, unused_variables)] @@ -12,15 +12,14 @@ struct Foo { } unsafe fn raw_to_ref<'a, T>(x: *const T) -> &'a T { - mem::transmute(x) + mem::transmute(x) //~ERROR: required 4 byte alignment } fn main() { // Try many times as this might work by chance. for _ in 0..20 { let foo = Foo { x: 42, y: 99 }; - // There seem to be implicit reborrows, which make the error already appear here - let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; //~ERROR: alignment 4 is required + let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; let i = *p; } } diff --git a/tests/fail/unaligned_pointers/reference_to_packed.stderr b/tests/fail/unaligned_pointers/reference_to_packed.stderr index 7c246706db..fb588854b2 100644 --- a/tests/fail/unaligned_pointers/reference_to_packed.stderr +++ b/tests/fail/unaligned_pointers/reference_to_packed.stderr @@ -1,13 +1,18 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) --> $DIR/reference_to_packed.rs:LL:CC | -LL | let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required +LL | mem::transmute(x) + | ^^^^^^^^^^^^^^^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information = note: BACKTRACE: - = note: inside `main` at $DIR/reference_to_packed.rs:LL:CC + = note: inside `raw_to_ref::<'_, i32>` at $DIR/reference_to_packed.rs:LL:CC +note: inside `main` + --> $DIR/reference_to_packed.rs:LL:CC + | +LL | let p: &i32 = unsafe { raw_to_ref(ptr::addr_of!(foo.x)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/unaligned_pointers/unaligned_ptr1.rs b/tests/fail/unaligned_pointers/unaligned_ptr1.rs index 921bcd6ce2..9c72781ee0 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr1.rs +++ b/tests/fail/unaligned_pointers/unaligned_ptr1.rs @@ -7,6 +7,6 @@ fn main() { let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. let x = &x[0] as *const _ as *const u32; // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. - let _x = unsafe { *x }; //~ERROR: memory with alignment 2, but alignment 4 is required + let _x = unsafe { *x }; //~ERROR: with alignment 2, but alignment 4 is required } } diff --git a/tests/fail/unaligned_pointers/unaligned_ptr1.stderr b/tests/fail/unaligned_pointers/unaligned_ptr1.stderr index 49292be9cd..daebabf455 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr1.stderr +++ b/tests/fail/unaligned_pointers/unaligned_ptr1.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr1.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/unaligned_ptr2.rs b/tests/fail/unaligned_pointers/unaligned_ptr2.rs index 8f597659f7..ac3062773d 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr2.rs +++ b/tests/fail/unaligned_pointers/unaligned_ptr2.rs @@ -8,5 +8,5 @@ fn main() { let x = (x.as_ptr() as *const u8).wrapping_offset(3) as *const u32; // This must fail because alignment is violated: the offset is not sufficiently aligned. // Also make the offset not a power of 2, that used to ICE. - let _x = unsafe { *x }; //~ERROR: memory with alignment 1, but alignment 4 is required + let _x = unsafe { *x }; //~ERROR: with alignment 1, but alignment 4 is required } diff --git a/tests/fail/unaligned_pointers/unaligned_ptr2.stderr b/tests/fail/unaligned_pointers/unaligned_ptr2.stderr index e75482f723..38902e693d 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr2.stderr +++ b/tests/fail/unaligned_pointers/unaligned_ptr2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr2.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/unaligned_ptr3.stderr b/tests/fail/unaligned_pointers/unaligned_ptr3.stderr index 50dd4fdfc8..36a13b6331 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr3.stderr +++ b/tests/fail/unaligned_pointers/unaligned_ptr3.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr3.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/unaligned_ptr4.stderr b/tests/fail/unaligned_pointers/unaligned_ptr4.stderr index 182f3e0f87..8d7a62c385 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr4.stderr +++ b/tests/fail/unaligned_pointers/unaligned_ptr4.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr4.rs:LL:CC | LL | let _val = unsafe { *ptr }; - | ^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs b/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs deleted file mode 100644 index b414b90547..0000000000 --- a/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.rs +++ /dev/null @@ -1,14 +0,0 @@ -// This should fail even without validation or Stacked Borrows. -//@compile-flags: -Zmiri-disable-validation -Zmiri-disable-stacked-borrows -Cdebug-assertions=no -use std::ptr; - -fn main() { - // Try many times as this might work by chance. - for _ in 0..20 { - let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. - let x = &x[0] as *const _ as *const u32; - // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. - // The deref is UB even if we just put the result into a raw pointer. - let _x = unsafe { ptr::addr_of!(*x) }; //~ ERROR: memory with alignment 2, but alignment 4 is required - } -} diff --git a/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.stderr b/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.stderr deleted file mode 100644 index 2d8b1bf745..0000000000 --- a/tests/fail/unaligned_pointers/unaligned_ptr_addr_of.stderr +++ /dev/null @@ -1,16 +0,0 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required - --> $DIR/unaligned_ptr_addr_of.rs:LL:CC - | -LL | let _x = unsafe { ptr::addr_of!(*x) }; - | ^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required - | - = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior - = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information - = note: BACKTRACE: - = note: inside `main` at RUSTLIB/core/src/ptr/mod.rs:LL:CC - = note: this error originates in the macro `ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) - -note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace - -error: aborting due to previous error - diff --git a/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr b/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr index aa0cbe1623..7481179f26 100644 --- a/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr +++ b/tests/fail/unaligned_pointers/unaligned_ptr_zst.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required +error: Undefined Behavior: accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required --> $DIR/unaligned_ptr_zst.rs:LL:CC | LL | let _x = unsafe { *x }; - | ^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | ^^ accessing memory based on pointer with alignment ALIGN, but alignment ALIGN is required | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs b/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs new file mode 100644 index 0000000000..470420acd5 --- /dev/null +++ b/tests/fail/unaligned_pointers/unaligned_ref_addr_of.rs @@ -0,0 +1,12 @@ +// This should fail even without Stacked Borrows. +//@compile-flags: -Zmiri-disable-stacked-borrows -Cdebug-assertions=no + +fn main() { + // Try many times as this might work by chance. + for _ in 0..20 { + let x = [2u16, 3, 4]; // Make it big enough so we don't get an out-of-bounds error. + let x = &x[0] as *const _ as *const u32; + // This must fail because alignment is violated: the allocation's base is not sufficiently aligned. + let _x = unsafe { &*x }; //~ ERROR: required 4 byte alignment + } +} diff --git a/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr b/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr new file mode 100644 index 0000000000..e47226ecdc --- /dev/null +++ b/tests/fail/unaligned_pointers/unaligned_ref_addr_of.stderr @@ -0,0 +1,15 @@ +error: Undefined Behavior: constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) + --> $DIR/unaligned_ref_addr_of.rs:LL:CC + | +LL | let _x = unsafe { &*x }; + | ^^^ constructing invalid value: encountered an unaligned reference (required ALIGN byte alignment but found ALIGN) + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `main` at $DIR/unaligned_ref_addr_of.rs:LL:CC + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/tests/fail/zst1.stderr b/tests/fail/zst1.stderr index b89f06af95..07bf048ab6 100644 --- a/tests/fail/zst1.stderr +++ b/tests/fail/zst1.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds --> $DIR/zst1.rs:LL:CC | LL | let _val = unsafe { *x }; - | ^^ dereferencing pointer failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds + | ^^ memory access failed: ALLOC has size 0, so pointer to 1 byte starting at offset 0 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/zst2.stderr b/tests/fail/zst2.stderr index 49954b1fd1..f42fb07edc 100644 --- a/tests/fail/zst2.stderr +++ b/tests/fail/zst2.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling +error: Undefined Behavior: memory access failed: ALLOC has been freed, so this pointer is dangling --> $DIR/zst2.rs:LL:CC | LL | unsafe { *x = zst_val }; - | ^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has been freed, so this pointer is dangling + | ^^^^^^^^^^^^ memory access failed: ALLOC has been freed, so this pointer is dangling | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/fail/zst3.stderr b/tests/fail/zst3.stderr index b62aef675d..f8b416ec34 100644 --- a/tests/fail/zst3.stderr +++ b/tests/fail/zst3.stderr @@ -1,8 +1,8 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds +error: Undefined Behavior: memory access failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds --> $DIR/zst3.rs:LL:CC | LL | unsafe { *(x as *mut [u8; 0]) = zst_val }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: ALLOC has size 1, so pointer at offset 2 is out-of-bounds | = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information diff --git a/tests/pass/function_calls/target_feature_wasm.rs b/tests/pass/function_calls/target_feature_wasm.rs new file mode 100644 index 0000000000..5056f32de4 --- /dev/null +++ b/tests/pass/function_calls/target_feature_wasm.rs @@ -0,0 +1,11 @@ +//@only-target-wasm32: tests WASM-specific behavior +//@compile-flags: -C target-feature=-simd128 + +fn main() { + // Calling functions with `#[target_feature]` is not unsound on WASM, see #84988 + assert!(!cfg!(target_feature = "simd128")); + simd128_fn(); +} + +#[target_feature(enable = "simd128")] +fn simd128_fn() {} diff --git a/tests/pass/ptr_raw.rs b/tests/pass/ptr_raw.rs index 2f18435890..11c3455a9c 100644 --- a/tests/pass/ptr_raw.rs +++ b/tests/pass/ptr_raw.rs @@ -1,3 +1,7 @@ +#![feature(strict_provenance)] +use std::mem; +use std::ptr::{self, addr_of}; + fn basic_raw() { let mut x = 12; let x = &mut x; @@ -28,7 +32,37 @@ fn assign_overlapping() { unsafe { *ptr = *ptr }; } +fn deref_invalid() { + unsafe { + // `addr_of!(*ptr)` is never UB. + let _val = addr_of!(*ptr::invalid::(0)); + let _val = addr_of!(*ptr::invalid::(1)); // not aligned + + // Similarly, just mentioning the place is fine. + let _ = *ptr::invalid::(0); + let _ = *ptr::invalid::(1); + } +} + +fn deref_partially_dangling() { + let x = (1, 13); + let xptr = &x as *const _ as *const (i32, i32, i32); + let val = unsafe { (*xptr).1 }; + assert_eq!(val, 13); +} + +fn deref_too_big_slice() { + unsafe { + let slice: *const [u8] = mem::transmute((1usize, usize::MAX)); + // `&*slice` would complain that the slice is too big, but in a raw pointer this is fine. + let _val = addr_of!(*slice); + } +} + fn main() { basic_raw(); assign_overlapping(); + deref_invalid(); + deref_partially_dangling(); + deref_too_big_slice(); }