From 13d425daebe539b1a48731faecf1d1ba5287aa72 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 21:14:18 -0400 Subject: [PATCH 01/10] make permissive provenance and raw-ptr tagging the default --- README.md | 25 ++---- src/bin/miri.rs | 7 +- src/diagnostics.rs | 25 +++++- src/eval.rs | 5 +- src/intptrcast.rs | 76 +++++++++---------- src/machine.rs | 3 +- src/stacked_borrows.rs | 8 +- test-cargo-miri/run-test.py | 5 -- .../fail/backtrace/bad-backtrace-flags.stderr | 17 ++++- tests/fail/backtrace/bad-backtrace-ptr.stderr | 17 ++++- .../bad-backtrace-resolve-flags.stderr | 17 ++++- .../bad-backtrace-resolve-names-flags.stderr | 17 ++++- .../thread_local_static_dealloc.stderr | 17 ++++- .../deref-invalid-ptr.stderr | 17 ++++- .../storage_dead_dangling.stderr | 22 +++++- .../wild_pointer_deref.stderr | 17 ++++- .../intrinsics/ptr_offset_0_plus_0.stderr | 17 ++++- .../intrinsics/ptr_offset_int_plus_int.stderr | 17 ++++- .../intrinsics/ptr_offset_int_plus_ptr.stderr | 17 ++++- .../fail/provenance/ptr_legacy_provenance.rs | 22 ------ .../provenance/ptr_legacy_provenance.stderr | 15 ---- .../fail/stacked_borrows/aliasing_mut3.stderr | 8 +- .../box_exclusive_violation1.rs | 4 +- .../box_exclusive_violation1.stderr | 33 ++++---- tests/fail/stacked_borrows/illegal_read3.rs | 2 +- .../fail/stacked_borrows/illegal_read6.stderr | 8 +- tests/fail/stacked_borrows/illegal_write1.rs | 4 +- .../stacked_borrows/illegal_write1.stderr | 21 ++--- .../stacked_borrows/illegal_write2.stderr | 8 +- .../stacked_borrows/illegal_write3.stderr | 6 +- tests/fail/stacked_borrows/illegal_write4.rs | 4 +- .../stacked_borrows/illegal_write4.stderr | 2 +- .../stacked_borrows/illegal_write6.stderr | 8 +- .../invalidate_against_barrier1.stderr | 8 +- .../invalidate_against_barrier2.stderr | 8 +- .../mut_exclusive_violation1.stderr | 8 +- .../stacked_borrows/outdated_local.stderr | 8 +- .../stacked_borrows/pointer_smuggling.stderr | 8 +- tests/fail/stacked_borrows/raw_tracking.rs | 1 - .../shr_frozen_violation1.stderr | 6 +- .../transmute-is-no-escape.stderr | 10 ++- .../stacked_borrows/unescaped_local.stderr | 32 ++++---- .../stacked_borrows/unescaped_static.stderr | 10 ++- .../intptrcast_alignment_check.stderr | 17 ++++- tests/fail/uninit_byte_read.rs | 1 + tests/fail/validity/cast_fn_ptr1.stderr | 17 ++++- tests/fail/validity/cast_fn_ptr2.stderr | 22 +++++- tests/pass/adjacent-allocs.rs | 2 + tests/pass/align.stderr | 20 +++++ tests/pass/box.rs | 2 +- tests/pass/box.stderr | 20 +++++ .../concurrency/tls_pthread_drop_order.rs | 7 +- tests/pass/extern_types.stderr | 15 ++++ tests/pass/intptrcast.rs | 2 + tests/pass/intrinsics.rs | 1 + .../pass/linux-getrandom-without-isolation.rs | 6 +- tests/pass/linux-getrandom.rs | 6 +- tests/pass/panic/catch_panic.rs | 2 +- tests/pass/ptr_int_casts.rs | 1 + tests/pass/ptr_offset.rs | 1 + tests/pass/stacked-borrows/2phase.rs | 2 - .../stacked-borrows/interior_mutability.rs | 1 - tests/pass/stacked-borrows/stacked-borrows.rs | 1 - tests/pass/zst.rs | 1 + 64 files changed, 491 insertions(+), 246 deletions(-) delete mode 100644 tests/fail/provenance/ptr_legacy_provenance.rs delete mode 100644 tests/fail/provenance/ptr_legacy_provenance.stderr create mode 100644 tests/pass/align.stderr create mode 100644 tests/pass/box.stderr create mode 100644 tests/pass/extern_types.stderr diff --git a/README.md b/README.md index 50586c9ece..efdbf5143d 100644 --- a/README.md +++ b/README.md @@ -306,7 +306,7 @@ environment variable. We first document the most relevant and most commonly used * `-Zmiri-strict-provenance` enables [strict provenance](https://github.com/rust-lang/rust/issues/95228) checking in Miri. This means that casting an integer to a pointer yields a result with 'invalid' provenance, i.e., with provenance - that cannot be used for any memory access. Also implies `-Zmiri-tag-raw-pointers`. + that cannot be used for any memory access. The remaining flags are for advanced use only, and more likely to change or be removed. Some of these are **unsound**, which means they can lead @@ -321,7 +321,7 @@ to Miri failing to detect cases of undefined behavior in a program. integers via `mem::transmute` or union/pointer type punning. This has two effects: it disables the check against integers storing a pointer (i.e., data with provenance), thus allowing pointer-to-integer transmutation, and it treats integer-to-pointer transmutation as equivalent to - a cast. Using this flag is **unsound** and + a cast. Implies `-Zmiri-permissive-provenance`. Using this flag is **unsound** and [deprecated](https://github.com/rust-lang/miri/issues/2188). * `-Zmiri-disable-abi-check` disables checking [function ABI]. Using this flag is **unsound**. @@ -354,15 +354,11 @@ to Miri failing to detect cases of undefined behavior in a program. application instead of raising an error within the context of Miri (and halting execution). Note that code might not expect these operations to ever panic, so this flag can lead to strange (mis)behavior. -* `-Zmiri-permissive-provenance` is **experimental**. This will make Miri do a - best-effort attempt to implement the semantics of - [`expose_addr`](https://doc.rust-lang.org/nightly/std/primitive.pointer.html#method.expose_addr) - and - [`ptr::from_exposed_addr`](https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html) - for pointer-to-int and int-to-pointer casts, respectively. This will - necessarily miss some bugs as those semantics are not efficiently - implementable in a sanitizer, but it will only miss bugs that concerns - memory/pointers which is subject to these operations. +* `-Zmiri-permissive-provenance` disables the warning for integer-to-pointer casts and + [`ptr::from_exposed_addr`](https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html). + This will necessarily miss some bugs as those operations are not efficiently and accurately + implementable in a sanitizer, but it will only miss bugs that concern memory/pointers which is + subject to these operations. * `-Zmiri-symbolic-alignment-check` makes the alignment check more strict. By default, alignment is checked by casting the pointer to an integer, and making sure that is a multiple of the alignment. This can lead to cases where a @@ -389,13 +385,6 @@ to Miri failing to detect cases of undefined behavior in a program. happening and where in your code would be a good place to look for it. Specifying this argument multiple times does not overwrite the previous values, instead it appends its values to the list. Listing a tag multiple times has no effect. -* `-Zmiri-tag-raw-pointers` makes Stacked Borrows assign proper tags even for raw pointers. This can - make valid code using int-to-ptr casts fail to pass the checks, but also can help identify latent - aliasing issues in code that Miri accepts by default. You can recognize false positives by - `` occurring in the message -- this indicates a pointer that was cast from an integer, - so Miri was unable to track this pointer. Note that it is not currently guaranteed that code that - works with `-Zmiri-tag-raw-pointers` also works without `-Zmiri-tag-raw-pointers`, but for the - vast majority of code, this will be the case. [function ABI]: https://doc.rust-lang.org/reference/items/functions.html#extern-function-qualifier diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 91148400c9..7bced91264 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -340,6 +340,7 @@ fn main() { Please let us know at if you rely on this flag." ); miri_config.allow_ptr_int_transmute = true; + miri_config.provenance_mode = ProvenanceMode::Permissive; } else if arg == "-Zmiri-disable-abi-check" { miri_config.check_abi = false; } else if arg == "-Zmiri-disable-isolation" { @@ -374,20 +375,18 @@ fn main() { } else if arg == "-Zmiri-panic-on-unsupported" { miri_config.panic_on_unsupported = true; } else if arg == "-Zmiri-tag-raw-pointers" { - miri_config.tag_raw = true; + eprintln!("WARNING: `-Zmiri-tag-raw-pointers` has no effect; it is enabled by default"); } else if arg == "-Zmiri-strict-provenance" { miri_config.provenance_mode = ProvenanceMode::Strict; - miri_config.tag_raw = true; + miri_config.allow_ptr_int_transmute = false; } else if arg == "-Zmiri-permissive-provenance" { miri_config.provenance_mode = ProvenanceMode::Permissive; - miri_config.tag_raw = true; } else if arg == "-Zmiri-mute-stdout-stderr" { miri_config.mute_stdout_stderr = true; } else if arg == "-Zmiri-track-raw-pointers" { eprintln!( "WARNING: -Zmiri-track-raw-pointers has been renamed to -Zmiri-tag-raw-pointers, the old name is deprecated." ); - miri_config.tag_raw = true; } else if let Some(param) = arg.strip_prefix("-Zmiri-seed=") { if miri_config.seed.is_some() { panic!("Cannot specify -Zmiri-seed multiple times!"); diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 6986d9c572..d17d1e6ed4 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -69,6 +69,7 @@ pub enum NonHaltingDiagnostic { FreedAlloc(AllocId), RejectedIsolatedOp(String), ProgressReport, + Int2Ptr, } /// Level of Miri specific diagnostics @@ -468,15 +469,35 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx format!("{op} was made to return an error due to isolation"), ProgressReport => format!("progress report: current operation being executed is here"), + Int2Ptr => format!("pointer-to-integer cast"), }; let (title, diag_level) = match e { RejectedIsolatedOp(_) => ("operation rejected by isolation", DiagLevel::Warning), - _ => ("tracking was triggered", DiagLevel::Note), + Int2Ptr => ("pointer-to-integer cast", DiagLevel::Warning), + CreatedPointerTag(..) + | PoppedPointerTag(..) + | CreatedCallId(..) + | CreatedAlloc(..) + | FreedAlloc(..) + | ProgressReport => ("tracking was triggered", DiagLevel::Note), }; - report_msg(this, diag_level, title, vec![msg], vec![], &stacktrace); + let helps = match e { + Int2Ptr => + vec![ + (None, format!("this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`,")), + (None, format!("which means that Miri might miss pointer bugs in this program")), + (None, format!("see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation")), + (None, format!("to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead")), + (None, format!("you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics")), + (None, format!("alternatively, the `-Zmiri-permissive-provenance` flag disables this warning")), + ], + _ => vec![], + }; + + report_msg(this, diag_level, title, vec![msg], helps, &stacktrace); } }); } diff --git a/src/eval.rs b/src/eval.rs index 7beb2ec9c4..fa252953fe 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -101,8 +101,6 @@ pub struct MiriConfig { pub tracked_call_ids: HashSet, /// The allocation ids to report about. pub tracked_alloc_ids: HashSet, - /// Whether to track raw pointers in stacked borrows. - pub tag_raw: bool, /// Determine if data race detection should be enabled pub data_race_detector: bool, /// Determine if weak memory emulation should be enabled. Requires data race detection to be enabled @@ -146,14 +144,13 @@ impl Default for MiriConfig { tracked_pointer_tags: HashSet::default(), tracked_call_ids: HashSet::default(), tracked_alloc_ids: HashSet::default(), - tag_raw: false, data_race_detector: true, weak_memory_emulation: true, cmpxchg_weak_failure_rate: 0.8, // 80% measureme_out: None, panic_on_unsupported: false, backtrace_style: BacktraceStyle::Short, - provenance_mode: ProvenanceMode::Legacy, + provenance_mode: ProvenanceMode::Default, mute_stdout_stderr: false, preemption_rate: 0.01, // 1% report_progress: None, diff --git a/src/intptrcast.rs b/src/intptrcast.rs index cfaf61f9d5..c92954a218 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -11,16 +11,13 @@ use crate::*; #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum ProvenanceMode { - /// Int2ptr casts return pointers with "wildcard" provenance - /// that basically matches that of all exposed pointers - /// (and SB tags, if enabled). + /// We support `expose_addr`/`from_exposed_addr` via "wildcard" provenance. + /// However, we want on `from_exposed_addr` to alert the user of the precision loss. + Default, + /// Like `Default`, but without the warning. Permissive, - /// Int2ptr casts return pointers with an invalid provenance, - /// i.e., not valid for any memory access. + /// We error on `from_exposed_addr`, ensuring no precision loss. Strict, - /// Int2ptr casts determine the allocation they point to at cast time. - /// All allocations are considered exposed. - Legacy, } pub type GlobalState = RefCell; @@ -66,6 +63,8 @@ impl<'mir, 'tcx> GlobalStateInner { let pos = global_state.int_to_ptr_map.binary_search_by_key(&addr, |(addr, _)| *addr); + // Determine the in-bounds provenance for this pointer. + // (This is only called on an actual access, so in-bounds is the only possible kind of provenance.) let alloc_id = match pos { Ok(pos) => Some(global_state.int_to_ptr_map[pos].1), Err(0) => None, @@ -91,21 +90,14 @@ impl<'mir, 'tcx> GlobalStateInner { } }?; - // In legacy mode, we consider all allocations exposed. - if global_state.provenance_mode == ProvenanceMode::Legacy - || global_state.exposed.contains(&alloc_id) - { - Some(alloc_id) - } else { - None - } + // We only use this provenance if it has been exposed. + if global_state.exposed.contains(&alloc_id) { Some(alloc_id) } else { None } } pub fn expose_ptr(ecx: &mut MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId, sb: SbTag) { let global_state = ecx.machine.intptrcast.get_mut(); - // In legacy and strict mode, we don't need this, so we can save some cycles - // by not tracking it. - if global_state.provenance_mode == ProvenanceMode::Permissive { + // In strict mode, we don't need this, so we can save some cycles by not tracking it. + if global_state.provenance_mode != ProvenanceMode::Strict { trace!("Exposing allocation id {alloc_id:?}"); global_state.exposed.insert(alloc_id); if ecx.machine.stacked_borrows.is_some() { @@ -120,42 +112,43 @@ impl<'mir, 'tcx> GlobalStateInner { ) -> Pointer> { trace!("Transmuting 0x{:x} to a pointer", addr); - if ecx.machine.allow_ptr_int_transmute { - // When we allow transmutes, treat them like casts. - Self::ptr_from_addr_cast(ecx, addr) + let provenance = if ecx.machine.allow_ptr_int_transmute { + // When we allow transmutes, treat them like casts: generating a wildcard pointer. + Some(Tag::Wildcard) } else { - // We consider transmuted pointers to be "invalid" (`None` provenance). - Pointer::new(None, Size::from_bytes(addr)) - } + // Usually, we consider transmuted pointers to be "invalid" (`None` provenance). + None + }; + Pointer::new(provenance, Size::from_bytes(addr)) } pub fn ptr_from_addr_cast( ecx: &MiriEvalContext<'mir, 'tcx>, addr: u64, - ) -> Pointer> { + ) -> InterpResult<'tcx, Pointer>> { trace!("Casting 0x{:x} to a pointer", addr); let global_state = ecx.machine.intptrcast.borrow(); match global_state.provenance_mode { - ProvenanceMode::Legacy => { - // Determine the allocation this points to at cast time. - let alloc_id = Self::alloc_id_from_addr(ecx, addr); - Pointer::new( - alloc_id.map(|alloc_id| Tag::Concrete { alloc_id, sb: SbTag::Untagged }), - Size::from_bytes(addr), - ) + ProvenanceMode::Default => { + // The first time this happens, print a warning. + use std::sync::atomic::{AtomicBool, Ordering}; + static FIRST_WARNING: AtomicBool = AtomicBool::new(true); + if FIRST_WARNING.swap(false, Ordering::Relaxed) { + register_diagnostic(NonHaltingDiagnostic::Int2Ptr); + } } ProvenanceMode::Strict => { - // We don't support int2ptr casts in this mode (i.e., we treat them like - // transmutes). - Pointer::new(None, Size::from_bytes(addr)) - } - ProvenanceMode::Permissive => { - // This is how wildcard pointers are born. - Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr)) + throw_unsup_format!( + "integer-to-pointer casts and `from_exposed_addr` are not supported with `-Zmiri-strict-provenance`; use `with_addr` instead" + ) } + ProvenanceMode::Permissive => {} } + + // This is how wildcard pointers are born. + Ok(Pointer::new(Some(Tag::Wildcard), Size::from_bytes(addr))) } fn alloc_base_addr(ecx: &MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId) -> u64 { @@ -214,6 +207,8 @@ impl<'mir, 'tcx> GlobalStateInner { dl.overflowing_offset(base_addr, offset.bytes()).0 } + /// Whena pointer is used for a memory access, this computes where in which allocation the + /// access is going. pub fn abs_ptr_to_rel( ecx: &MiriEvalContext<'mir, 'tcx>, ptr: Pointer, @@ -224,7 +219,6 @@ impl<'mir, 'tcx> GlobalStateInner { alloc_id } else { // A wildcard pointer. - assert_eq!(ecx.machine.intptrcast.borrow().provenance_mode, ProvenanceMode::Permissive); GlobalStateInner::alloc_id_from_addr(ecx, addr.bytes())? }; diff --git a/src/machine.rs b/src/machine.rs index 3621744e80..d6a65a2a44 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -353,7 +353,6 @@ impl<'mir, 'tcx> Evaluator<'mir, 'tcx> { Some(RefCell::new(stacked_borrows::GlobalStateInner::new( config.tracked_pointer_tags.clone(), config.tracked_call_ids.clone(), - config.tag_raw, ))) } else { None @@ -696,7 +695,7 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> { ecx: &MiriEvalContext<'mir, 'tcx>, addr: u64, ) -> InterpResult<'tcx, Pointer>> { - Ok(intptrcast::GlobalStateInner::ptr_from_addr_cast(ecx, addr)) + intptrcast::GlobalStateInner::ptr_from_addr_cast(ecx, addr) } #[inline(always)] diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index 6fa70ddfc5..2340802762 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -219,11 +219,7 @@ impl fmt::Display for RefKind { /// Utilities for initialization and ID generation impl GlobalStateInner { - pub fn new( - tracked_pointer_tags: HashSet, - tracked_call_ids: HashSet, - tag_raw: bool, - ) -> Self { + pub fn new(tracked_pointer_tags: HashSet, tracked_call_ids: HashSet) -> Self { GlobalStateInner { next_ptr_id: NonZeroU64::new(1).unwrap(), base_ptr_ids: FxHashMap::default(), @@ -231,7 +227,7 @@ impl GlobalStateInner { active_calls: FxHashSet::default(), tracked_pointer_tags, tracked_call_ids, - tag_raw, + tag_raw: true, } } diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 1996563948..42978c481b 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -124,11 +124,6 @@ def test_cargo_miri_test(): "test.cross-target.stdout.ref", "test.stderr-empty.ref", env={'MIRIFLAGS': "-Zmiri-disable-isolation"}, ) - test("`cargo miri test` (raw-ptr tracking)", - cargo_miri("test"), - default_ref, "test.stderr-empty.ref", - env={'MIRIFLAGS': "-Zmiri-tag-raw-pointers"}, - ) test("`cargo miri test` (with filter)", cargo_miri("test") + ["--", "--format=pretty", "le1"], filter_ref, "test.stderr-empty.ref", diff --git a/tests/fail/backtrace/bad-backtrace-flags.stderr b/tests/fail/backtrace/bad-backtrace-flags.stderr index f6ffe3c93c..ba16335fce 100644 --- a/tests/fail/backtrace/bad-backtrace-flags.stderr +++ b/tests/fail/backtrace/bad-backtrace-flags.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/bad-backtrace-flags.rs:LL:CC + | +LL | miri_get_backtrace(2, 0 as *mut _); + | ^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/bad-backtrace-flags.rs:LL:CC + error: unsupported operation: unknown `miri_get_backtrace` flags 2 --> $DIR/bad-backtrace-flags.rs:LL:CC | @@ -10,5 +25,5 @@ LL | miri_get_backtrace(2, 0 as *mut _); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/backtrace/bad-backtrace-ptr.stderr b/tests/fail/backtrace/bad-backtrace-ptr.stderr index ed726a5dcd..75268b6671 100644 --- a/tests/fail/backtrace/bad-backtrace-ptr.stderr +++ b/tests/fail/backtrace/bad-backtrace-ptr.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/bad-backtrace-ptr.rs:LL:CC + | +LL | miri_resolve_frame(0 as *mut _, 0); + | ^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/bad-backtrace-ptr.rs:LL:CC + error: Undefined Behavior: null pointer is not a valid pointer for this operation --> $DIR/bad-backtrace-ptr.rs:LL:CC | @@ -11,5 +26,5 @@ LL | miri_resolve_frame(0 as *mut _, 0); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr b/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr index 49495651df..fad9ffe119 100644 --- a/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr +++ b/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/bad-backtrace-resolve-flags.rs:LL:CC + | +LL | let mut buf = vec![0 as *mut _; miri_backtrace_size(0)]; + | ^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/bad-backtrace-resolve-flags.rs:LL:CC + error: unsupported operation: unknown `miri_resolve_frame` flags 2 --> $DIR/bad-backtrace-resolve-flags.rs:LL:CC | @@ -10,5 +25,5 @@ LL | miri_resolve_frame(buf[0], 2); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr b/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr index d575caa4ff..18b03df21c 100644 --- a/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr +++ b/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC + | +LL | let mut buf = vec![0 as *mut _; miri_backtrace_size(0)]; + | ^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC + error: unsupported operation: unknown `miri_resolve_frame_names` flags 2 --> $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC | @@ -10,5 +25,5 @@ LL | ... miri_resolve_frame_names(buf[0], 2, 0 as *mut _, 0 as *mut _); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/concurrency/thread_local_static_dealloc.stderr b/tests/fail/concurrency/thread_local_static_dealloc.stderr index 2a3a8f0f55..31a64eec36 100644 --- a/tests/fail/concurrency/thread_local_static_dealloc.stderr +++ b/tests/fail/concurrency/thread_local_static_dealloc.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/thread_local_static_dealloc.rs:LL:CC + | +LL | let _val = *(dangling_ptr as *const u8); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/thread_local_static_dealloc.rs:LL:CC + error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed --> $DIR/thread_local_static_dealloc.rs:LL:CC | @@ -11,5 +26,5 @@ LL | let _val = *(dangling_ptr as *const u8); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/dangling_pointers/deref-invalid-ptr.stderr b/tests/fail/dangling_pointers/deref-invalid-ptr.stderr index f4361d9fef..ffd7fb1980 100644 --- a/tests/fail/dangling_pointers/deref-invalid-ptr.stderr +++ b/tests/fail/dangling_pointers/deref-invalid-ptr.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/deref-invalid-ptr.rs:LL:CC + | +LL | let x = 16usize as *const u32; + | ^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/deref-invalid-ptr.rs:LL:CC + error: Undefined Behavior: dereferencing pointer failed: 0x10 is not a valid pointer --> $DIR/deref-invalid-ptr.rs:LL:CC | @@ -11,5 +26,5 @@ LL | let _y = unsafe { &*x as *const u32 }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/tests/fail/dangling_pointers/storage_dead_dangling.stderr index aed14105ad..3a94a7fa58 100644 --- a/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -1,3 +1,23 @@ +warning: pointer-to-integer cast + --> $DIR/storage_dead_dangling.rs:LL:CC + | +LL | unsafe { &mut *(LEAK as *mut i32) }; + | ^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `evil` at $DIR/storage_dead_dangling.rs:LL:CC +note: inside `main` at $DIR/storage_dead_dangling.rs:LL:CC + --> $DIR/storage_dead_dangling.rs:LL:CC + | +LL | evil(); + | ^^^^^^ + error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed --> $DIR/storage_dead_dangling.rs:LL:CC | @@ -16,5 +36,5 @@ LL | evil(); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/dangling_pointers/wild_pointer_deref.stderr b/tests/fail/dangling_pointers/wild_pointer_deref.stderr index b20f310da0..960f9c9ce3 100644 --- a/tests/fail/dangling_pointers/wild_pointer_deref.stderr +++ b/tests/fail/dangling_pointers/wild_pointer_deref.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/wild_pointer_deref.rs:LL:CC + | +LL | let p = 44 as *const i32; + | ^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/wild_pointer_deref.rs:LL:CC + error: Undefined Behavior: dereferencing pointer failed: 0x2c is not a valid pointer --> $DIR/wild_pointer_deref.rs:LL:CC | @@ -11,5 +26,5 @@ LL | let x = unsafe { *p }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr b/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr index 741314ea8a..2474820545 100644 --- a/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr +++ b/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/ptr_offset_0_plus_0.rs:LL:CC + | +LL | let x = 0 as *mut i32; + | ^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/ptr_offset_0_plus_0.rs:LL:CC + error: Undefined Behavior: pointer arithmetic failed: null pointer is not a valid pointer --> RUSTLIB/core/src/ptr/mut_ptr.rs:LL:CC | @@ -16,5 +31,5 @@ LL | let _x = unsafe { x.offset(0) }; // UB despite offset 0, NULL is never note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr b/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr index e6b8f102f3..f5cbd4bbbf 100644 --- a/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr +++ b/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/ptr_offset_int_plus_int.rs:LL:CC + | +LL | let _val = (1 as *mut u8).offset(1); + | ^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/ptr_offset_int_plus_int.rs:LL:CC + error: Undefined Behavior: pointer arithmetic failed: 0x1 is not a valid pointer --> RUSTLIB/core/src/ptr/mut_ptr.rs:LL:CC | @@ -16,5 +31,5 @@ LL | let _val = (1 as *mut u8).offset(1); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr b/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr index f88ad758d4..577a377f07 100644 --- a/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr +++ b/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/ptr_offset_int_plus_ptr.rs:LL:CC + | +LL | let _val = (1 as *mut u8).offset(ptr as isize); + | ^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/ptr_offset_int_plus_ptr.rs:LL:CC + error: Undefined Behavior: pointer arithmetic failed: 0x1 is not a valid pointer --> RUSTLIB/core/src/ptr/mut_ptr.rs:LL:CC | @@ -16,5 +31,5 @@ LL | let _val = (1 as *mut u8).offset(ptr as isize); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/provenance/ptr_legacy_provenance.rs b/tests/fail/provenance/ptr_legacy_provenance.rs deleted file mode 100644 index 538ec4484e..0000000000 --- a/tests/fail/provenance/ptr_legacy_provenance.rs +++ /dev/null @@ -1,22 +0,0 @@ -// compile-flags: -Zmiri-disable-stacked-borrows -// normalize-stderr-test: "offset -[0-9]+" -> "offset -XX" -#![feature(strict_provenance)] - -use std::ptr; - -// Make sure that with legacy provenance, the allocation id of -// a casted pointer is determined at cast-time -fn main() { - let x: i32 = 0; - let y: i32 = 1; - - let x_ptr = &x as *const i32; - let y_ptr = &y as *const i32; - - let x_usize = x_ptr.expose_addr(); - let y_usize = y_ptr.expose_addr(); - - let ptr = ptr::from_exposed_addr::(y_usize); - let ptr = ptr.with_addr(x_usize); - assert_eq!(unsafe { *ptr }, 0); //~ ERROR is out-of-bounds -} diff --git a/tests/fail/provenance/ptr_legacy_provenance.stderr b/tests/fail/provenance/ptr_legacy_provenance.stderr deleted file mode 100644 index 4552be0814..0000000000 --- a/tests/fail/provenance/ptr_legacy_provenance.stderr +++ /dev/null @@ -1,15 +0,0 @@ -error: Undefined Behavior: dereferencing pointer failed: ALLOC has size 4, so pointer to 4 bytes starting at offset -XX is out-of-bounds - --> $DIR/ptr_legacy_provenance.rs:LL:CC - | -LL | assert_eq!(unsafe { *ptr }, 0); - | ^^^^ dereferencing pointer failed: ALLOC has size 4, so pointer to 4 bytes starting at offset -XX 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 - - = note: inside `main` at $DIR/ptr_legacy_provenance.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/stacked_borrows/aliasing_mut3.stderr b/tests/fail/stacked_borrows/aliasing_mut3.stderr index a4187be0a2..66220cfbfc 100644 --- a/tests/fail/stacked_borrows/aliasing_mut3.stderr +++ b/tests/fail/stacked_borrows/aliasing_mut3.stderr @@ -1,20 +1,20 @@ -error: Undefined Behavior: trying to reborrow for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: trying to reborrow for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/aliasing_mut3.rs:LL:CC | LL | pub fn safe(_x: &mut i32, _y: &i32) {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | trying to reborrow for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | trying to reborrow for SharedReadOnly permission at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of a reborrow at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/aliasing_mut3.rs:LL:CC | LL | safe_raw(xraw, xshr); | ^^^^ -help: tag was later invalidated at offsets [0x0..0x4] +help: was later invalidated at offsets [0x0..0x4] --> $DIR/aliasing_mut3.rs:LL:CC | LL | pub fn safe(_x: &mut i32, _y: &i32) {} diff --git a/tests/fail/stacked_borrows/box_exclusive_violation1.rs b/tests/fail/stacked_borrows/box_exclusive_violation1.rs index 3ca480ae7a..66d092d627 100644 --- a/tests/fail/stacked_borrows/box_exclusive_violation1.rs +++ b/tests/fail/stacked_borrows/box_exclusive_violation1.rs @@ -8,7 +8,7 @@ fn demo_mut_advanced_unique(mut our: Box) -> i32 { unknown_code_2(); // We know this will return 5 - *our //~ ERROR borrow stack + *our } // Now comes the evil context @@ -24,7 +24,7 @@ fn unknown_code_1(x: &i32) { fn unknown_code_2() { unsafe { - *LEAK = 7; + *LEAK = 7; //~ ERROR borrow stack } } diff --git a/tests/fail/stacked_borrows/box_exclusive_violation1.stderr b/tests/fail/stacked_borrows/box_exclusive_violation1.stderr index 3c3e6bbf1b..06c2dc340b 100644 --- a/tests/fail/stacked_borrows/box_exclusive_violation1.stderr +++ b/tests/fail/stacked_borrows/box_exclusive_violation1.stderr @@ -1,31 +1,30 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/box_exclusive_violation1.rs:LL:CC | -LL | *our - | ^^^^ - | | - | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - | this error occurs as part of an access at ALLOC[0x0..0x4] +LL | *LEAK = 7; + | ^^^^^^^^^ + | | + | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information help: was created by a retag at offsets [0x0..0x4] --> $DIR/box_exclusive_violation1.rs:LL:CC | -LL | / fn demo_mut_advanced_unique(mut our: Box) -> i32 { -LL | | unknown_code_1(&*our); -LL | | -LL | | // This "re-asserts" uniqueness of the reference: After writing, we know -... | -LL | | *our -LL | | } - | |_^ +LL | LEAK = x as *const _ as *mut _; + | ^ help: was later invalidated at offsets [0x0..0x4] --> $DIR/box_exclusive_violation1.rs:LL:CC | -LL | *LEAK = 7; - | ^^^^^^^^^ - = note: inside `demo_mut_advanced_unique` at $DIR/box_exclusive_violation1.rs:LL:CC +LL | *our = 5; + | ^^^^^^^^ + = note: inside `unknown_code_2` at $DIR/box_exclusive_violation1.rs:LL:CC +note: inside `demo_mut_advanced_unique` at $DIR/box_exclusive_violation1.rs:LL:CC + --> $DIR/box_exclusive_violation1.rs:LL:CC + | +LL | unknown_code_2(); + | ^^^^^^^^^^^^^^^^ note: inside `main` at $DIR/box_exclusive_violation1.rs:LL:CC --> $DIR/box_exclusive_violation1.rs:LL:CC | diff --git a/tests/fail/stacked_borrows/illegal_read3.rs b/tests/fail/stacked_borrows/illegal_read3.rs index 3de8f57d62..0173ca14b2 100644 --- a/tests/fail/stacked_borrows/illegal_read3.rs +++ b/tests/fail/stacked_borrows/illegal_read3.rs @@ -5,7 +5,7 @@ use std::mem; union HiddenRef { - // We avoid retagging at this type, so shared vs mutable does not matter. + // We avoid retagging at this type, and we only read, so shared vs mutable does not matter. r: &'static i32, } diff --git a/tests/fail/stacked_borrows/illegal_read6.stderr b/tests/fail/stacked_borrows/illegal_read6.stderr index 9782f1aa3a..2098dbdc6a 100644 --- a/tests/fail/stacked_borrows/illegal_read6.stderr +++ b/tests/fail/stacked_borrows/illegal_read6.stderr @@ -1,20 +1,20 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/illegal_read6.rs:LL:CC | LL | let _val = *raw; | ^^^^ | | - | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/illegal_read6.rs:LL:CC | LL | let raw = x as *mut _; | ^ -help: tag was later invalidated at offsets [0x0..0x4] +help: was later invalidated at offsets [0x0..0x4] --> $DIR/illegal_read6.rs:LL:CC | LL | let x = &mut *x; // kill `raw` diff --git a/tests/fail/stacked_borrows/illegal_write1.rs b/tests/fail/stacked_borrows/illegal_write1.rs index 1f566f18c1..58600402e4 100644 --- a/tests/fail/stacked_borrows/illegal_write1.rs +++ b/tests/fail/stacked_borrows/illegal_write1.rs @@ -3,7 +3,7 @@ fn main() { let xref = &*target; { let x: *mut u32 = xref as *const _ as *mut _; - unsafe { *x = 42 }; // invalidates shared ref, activates raw + unsafe { *x = 42 }; //~ ERROR only grants SharedReadOnly permission } - let _x = *xref; //~ ERROR borrow stack + let _x = *xref; } diff --git a/tests/fail/stacked_borrows/illegal_write1.stderr b/tests/fail/stacked_borrows/illegal_write1.stderr index 1731e3c1de..b2084da862 100644 --- a/tests/fail/stacked_borrows/illegal_write1.stderr +++ b/tests/fail/stacked_borrows/illegal_write1.stderr @@ -1,24 +1,19 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location --> $DIR/illegal_write1.rs:LL:CC | -LL | let _x = *xref; - | ^^^^^ - | | - | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location - | this error occurs as part of an access at ALLOC[0x0..0x4] +LL | unsafe { *x = 42 }; + | ^^^^^^^ + | | + | attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location + | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information help: was created by a retag at offsets [0x0..0x4] --> $DIR/illegal_write1.rs:LL:CC | -LL | let xref = &*target; - | ^^^^^^^^ -help: was later invalidated at offsets [0x0..0x4] - --> $DIR/illegal_write1.rs:LL:CC - | -LL | unsafe { *x = 42 }; // invalidates shared ref, activates raw - | ^^^^^^^ +LL | let x: *mut u32 = xref as *const _ as *mut _; + | ^^^^ = note: inside `main` at $DIR/illegal_write1.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/stacked_borrows/illegal_write2.stderr b/tests/fail/stacked_borrows/illegal_write2.stderr index 7e896c530a..09784bd79a 100644 --- a/tests/fail/stacked_borrows/illegal_write2.stderr +++ b/tests/fail/stacked_borrows/illegal_write2.stderr @@ -1,20 +1,20 @@ -error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/illegal_write2.rs:LL:CC | LL | unsafe { *target2 = 13 }; | ^^^^^^^^^^^^^ | | - | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/illegal_write2.rs:LL:CC | LL | let target2 = target as *mut _; | ^^^^^^ -help: tag was later invalidated at offsets [0x0..0x4] +help: was later invalidated at offsets [0x0..0x4] --> $DIR/illegal_write2.rs:LL:CC | LL | drop(&mut *target); // reborrow diff --git a/tests/fail/stacked_borrows/illegal_write3.stderr b/tests/fail/stacked_borrows/illegal_write3.stderr index 7e9c82769d..983894dad0 100644 --- a/tests/fail/stacked_borrows/illegal_write3.stderr +++ b/tests/fail/stacked_borrows/illegal_write3.stderr @@ -1,15 +1,15 @@ -error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location --> $DIR/illegal_write3.rs:LL:CC | LL | unsafe { *ptr = 42 }; | ^^^^^^^^^ | | - | attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location + | attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/illegal_write3.rs:LL:CC | LL | let ptr = r#ref as *const _ as *mut _; // raw ptr, with raw tag diff --git a/tests/fail/stacked_borrows/illegal_write4.rs b/tests/fail/stacked_borrows/illegal_write4.rs index be4f89ba28..654a23d382 100644 --- a/tests/fail/stacked_borrows/illegal_write4.rs +++ b/tests/fail/stacked_borrows/illegal_write4.rs @@ -6,8 +6,8 @@ fn main() { // Even just creating it unfreezes. let raw = &mut target as *mut _; // let this leak to raw let reference = unsafe { &*raw }; // freeze - let ptr = reference as *const _ as *mut i32; // raw ptr, with raw tag - let _mut_ref: &mut i32 = unsafe { mem::transmute(ptr) }; // &mut, with raw tag + let _ptr = reference as *const _ as *mut i32; // raw ptr, with raw tag + let _mut_ref: &mut i32 = unsafe { mem::transmute(raw) }; // &mut, with raw tag // Now we retag, making our ref top-of-stack -- and, in particular, unfreezing. let _val = *reference; //~ ERROR borrow stack } diff --git a/tests/fail/stacked_borrows/illegal_write4.stderr b/tests/fail/stacked_borrows/illegal_write4.stderr index 404e13d113..ac4dd68bbc 100644 --- a/tests/fail/stacked_borrows/illegal_write4.stderr +++ b/tests/fail/stacked_borrows/illegal_write4.stderr @@ -17,7 +17,7 @@ LL | let reference = unsafe { &*raw }; // freeze help: was later invalidated at offsets [0x0..0x4] --> $DIR/illegal_write4.rs:LL:CC | -LL | let _mut_ref: &mut i32 = unsafe { mem::transmute(ptr) }; // &mut, with raw tag +LL | let _mut_ref: &mut i32 = unsafe { mem::transmute(raw) }; // &mut, with raw tag | ^^^^^^^^^^^^^^^^^^^ = note: inside `main` at $DIR/illegal_write4.rs:LL:CC diff --git a/tests/fail/stacked_borrows/illegal_write6.stderr b/tests/fail/stacked_borrows/illegal_write6.stderr index 11757cca9b..563397e062 100644 --- a/tests/fail/stacked_borrows/illegal_write6.stderr +++ b/tests/fail/stacked_borrows/illegal_write6.stderr @@ -1,17 +1,17 @@ -error: Undefined Behavior: not granting access to tag because incompatible item is protected: [Unique for (call ID)] +error: Undefined Behavior: not granting access to tag because incompatible item is protected: [Unique for (call ID)] --> $DIR/illegal_write6.rs:LL:CC | LL | unsafe { *y = 2 }; - | ^^^^^^ not granting access to tag because incompatible item is protected: [Unique for (call ID)] + | ^^^^^^ not granting access to tag because incompatible item is protected: [Unique for (call ID)] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/illegal_write6.rs:LL:CC | LL | let p = x as *mut u32; | ^ -help: was protected due to a tag which was created here +help: was protected due to which was created here --> $DIR/illegal_write6.rs:LL:CC | LL | foo(x, p); diff --git a/tests/fail/stacked_borrows/invalidate_against_barrier1.stderr b/tests/fail/stacked_borrows/invalidate_against_barrier1.stderr index 08d597ea18..826cdc9b5f 100644 --- a/tests/fail/stacked_borrows/invalidate_against_barrier1.stderr +++ b/tests/fail/stacked_borrows/invalidate_against_barrier1.stderr @@ -1,17 +1,17 @@ -error: Undefined Behavior: not granting access to tag because incompatible item is protected: [Unique for (call ID)] +error: Undefined Behavior: not granting access to tag because incompatible item is protected: [Unique for (call ID)] --> $DIR/invalidate_against_barrier1.rs:LL:CC | LL | let _val = unsafe { *x }; - | ^^ not granting access to tag because incompatible item is protected: [Unique for (call ID)] + | ^^ not granting access to tag because incompatible item is protected: [Unique for (call ID)] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/invalidate_against_barrier1.rs:LL:CC | LL | let xraw = &mut x as *mut _; | ^^^^^^ -help: was protected due to a tag which was created here +help: was protected due to which was created here --> $DIR/invalidate_against_barrier1.rs:LL:CC | LL | inner(xraw, xref); diff --git a/tests/fail/stacked_borrows/invalidate_against_barrier2.stderr b/tests/fail/stacked_borrows/invalidate_against_barrier2.stderr index 6aefa216ed..1cf90f91db 100644 --- a/tests/fail/stacked_borrows/invalidate_against_barrier2.stderr +++ b/tests/fail/stacked_borrows/invalidate_against_barrier2.stderr @@ -1,17 +1,17 @@ -error: Undefined Behavior: not granting access to tag because incompatible item is protected: [SharedReadOnly for (call ID)] +error: Undefined Behavior: not granting access to tag because incompatible item is protected: [SharedReadOnly for (call ID)] --> $DIR/invalidate_against_barrier2.rs:LL:CC | LL | unsafe { *x = 0 }; - | ^^^^^^ not granting access to tag because incompatible item is protected: [SharedReadOnly for (call ID)] + | ^^^^^^ not granting access to tag because incompatible item is protected: [SharedReadOnly for (call ID)] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/invalidate_against_barrier2.rs:LL:CC | LL | let xraw = &mut x as *mut _; | ^^^^^^ -help: was protected due to a tag which was created here +help: was protected due to which was created here --> $DIR/invalidate_against_barrier2.rs:LL:CC | LL | inner(xraw, xref); diff --git a/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr b/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr index ea14536a39..8afb4fee18 100644 --- a/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr +++ b/tests/fail/stacked_borrows/mut_exclusive_violation1.stderr @@ -1,20 +1,20 @@ -error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/mut_exclusive_violation1.rs:LL:CC | LL | *LEAK = 7; | ^^^^^^^^^ | | - | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/mut_exclusive_violation1.rs:LL:CC | LL | LEAK = x as *const _ as *mut _; | ^ -help: tag was later invalidated at offsets [0x0..0x4] +help: was later invalidated at offsets [0x0..0x4] --> $DIR/mut_exclusive_violation1.rs:LL:CC | LL | *our = 5; diff --git a/tests/fail/stacked_borrows/outdated_local.stderr b/tests/fail/stacked_borrows/outdated_local.stderr index fe3bdd00f4..c218d500cf 100644 --- a/tests/fail/stacked_borrows/outdated_local.stderr +++ b/tests/fail/stacked_borrows/outdated_local.stderr @@ -1,20 +1,20 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/outdated_local.rs:LL:CC | LL | assert_eq!(unsafe { *y }, 1); | ^^ | | - | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/outdated_local.rs:LL:CC | LL | let y: *const i32 = &x; | ^^ -help: tag was later invalidated at offsets [0x0..0x4] +help: was later invalidated at offsets [0x0..0x4] --> $DIR/outdated_local.rs:LL:CC | LL | x = 1; // this invalidates y by reactivating the lowermost uniq borrow for this local diff --git a/tests/fail/stacked_borrows/pointer_smuggling.stderr b/tests/fail/stacked_borrows/pointer_smuggling.stderr index 68ac631ec0..a3ab1b9fc5 100644 --- a/tests/fail/stacked_borrows/pointer_smuggling.stderr +++ b/tests/fail/stacked_borrows/pointer_smuggling.stderr @@ -1,20 +1,20 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/pointer_smuggling.rs:LL:CC | LL | let _x = unsafe { *PTR }; | ^^^^ | | - | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a read access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x1] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x1] +help: was created by a retag at offsets [0x0..0x1] --> $DIR/pointer_smuggling.rs:LL:CC | LL | PTR = x; | ^ -help: tag was later invalidated at offsets [0x0..0x1] +help: was later invalidated at offsets [0x0..0x1] --> $DIR/pointer_smuggling.rs:LL:CC | LL | *val = 2; // this invalidates any raw ptrs `fun1` might have created. diff --git a/tests/fail/stacked_borrows/raw_tracking.rs b/tests/fail/stacked_borrows/raw_tracking.rs index 0b9c058f06..49fe983125 100644 --- a/tests/fail/stacked_borrows/raw_tracking.rs +++ b/tests/fail/stacked_borrows/raw_tracking.rs @@ -1,4 +1,3 @@ -// compile-flags: -Zmiri-tag-raw-pointers //! This demonstrates a provenance problem that requires tracking of raw pointers to be detected. fn main() { diff --git a/tests/fail/stacked_borrows/shr_frozen_violation1.stderr b/tests/fail/stacked_borrows/shr_frozen_violation1.stderr index 0808d8471b..5587230071 100644 --- a/tests/fail/stacked_borrows/shr_frozen_violation1.stderr +++ b/tests/fail/stacked_borrows/shr_frozen_violation1.stderr @@ -1,15 +1,15 @@ -error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location --> $DIR/shr_frozen_violation1.rs:LL:CC | LL | *(x as *const i32 as *mut i32) = 7; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | | - | attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location + | attempting a write access using at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] +help: was created by a retag at offsets [0x0..0x4] --> $DIR/shr_frozen_violation1.rs:LL:CC | LL | *(x as *const i32 as *mut i32) = 7; diff --git a/tests/fail/stacked_borrows/transmute-is-no-escape.stderr b/tests/fail/stacked_borrows/transmute-is-no-escape.stderr index a9682f806b..91c3ff9f86 100644 --- a/tests/fail/stacked_borrows/transmute-is-no-escape.stderr +++ b/tests/fail/stacked_borrows/transmute-is-no-escape.stderr @@ -1,15 +1,19 @@ -error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location --> $DIR/transmute-is-no-escape.rs:LL:CC | LL | unsafe { *raw = 13 }; | ^^^^^^^^^ | | - | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information - +help: was created by a retag at offsets [0x4..0x8] + --> $DIR/transmute-is-no-escape.rs:LL:CC + | +LL | let raw = (&mut x[1] as *mut i32).wrapping_offset(-1); + | ^^^^^^^^^ = note: inside `main` at $DIR/transmute-is-no-escape.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/stacked_borrows/unescaped_local.stderr b/tests/fail/stacked_borrows/unescaped_local.stderr index 616c60b8aa..2f6605c058 100644 --- a/tests/fail/stacked_borrows/unescaped_local.stderr +++ b/tests/fail/stacked_borrows/unescaped_local.stderr @@ -1,27 +1,33 @@ -error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location +warning: pointer-to-integer cast + --> $DIR/unescaped_local.rs:LL:CC + | +LL | let raw = &mut x as *mut i32 as usize as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/unescaped_local.rs:LL:CC + +error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but no exposed tags have suitable permission in the borrow stack for this location --> $DIR/unescaped_local.rs:LL:CC | LL | *raw = 13; | ^^^^^^^^^ | | - | attempting a write access using at ALLOC[0x0], but that tag does not exist in the borrow stack for this location + | attempting a write access using at ALLOC[0x0], but no exposed tags have suitable permission in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x0..0x4] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information -help: tag was most recently created at offsets [0x0..0x4] - --> $DIR/unescaped_local.rs:LL:CC - | -LL | let raw = &mut x as *mut i32 as usize as *mut i32; - | ^^^^^^ -help: tag was later invalidated at offsets [0x0..0x4] - --> $DIR/unescaped_local.rs:LL:CC - | -LL | let _ptr = &mut x; - | ^^^^^^ + = note: inside `main` at $DIR/unescaped_local.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/stacked_borrows/unescaped_static.stderr b/tests/fail/stacked_borrows/unescaped_static.stderr index a0ac19f042..621e9617fd 100644 --- a/tests/fail/stacked_borrows/unescaped_static.stderr +++ b/tests/fail/stacked_borrows/unescaped_static.stderr @@ -1,15 +1,19 @@ -error: Undefined Behavior: attempting a read access using at ALLOC[0x1], but that tag does not exist in the borrow stack for this location +error: Undefined Behavior: attempting a read access using at ALLOC[0x1], but that tag does not exist in the borrow stack for this location --> $DIR/unescaped_static.rs:LL:CC | LL | let _val = unsafe { *ptr_to_first.add(1) }; | ^^^^^^^^^^^^^^^^^^^^ | | - | attempting a read access using at ALLOC[0x1], but that tag does not exist in the borrow stack for this location + | attempting a read access using at ALLOC[0x1], but that tag does not exist in the borrow stack for this location | this error occurs as part of an access at ALLOC[0x1..0x2] | = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information - +help: was created by a retag at offsets [0x0..0x1] + --> $DIR/unescaped_static.rs:LL:CC + | +LL | let ptr_to_first = &ARRAY[0] as *const u8; + | ^^^^^^^^^ = note: inside `main` at $DIR/unescaped_static.rs:LL:CC note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace diff --git a/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr b/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr index 347486187e..bd8d161de8 100644 --- a/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr +++ b/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/intptrcast_alignment_check.rs:LL:CC + | +LL | let u16_ptr = base_addr_aligned as *mut u16; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/intptrcast_alignment_check.rs:LL:CC + error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required --> $DIR/intptrcast_alignment_check.rs:LL:CC | @@ -11,5 +26,5 @@ LL | unsafe { *u16_ptr = 2 }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/uninit_byte_read.rs b/tests/fail/uninit_byte_read.rs index 6868e58955..683088e78b 100644 --- a/tests/fail/uninit_byte_read.rs +++ b/tests/fail/uninit_byte_read.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmiri-disable-stacked-borrows fn main() { let v: Vec = Vec::with_capacity(10); let undef = unsafe { *v.get_unchecked(5) }; //~ ERROR uninitialized diff --git a/tests/fail/validity/cast_fn_ptr1.stderr b/tests/fail/validity/cast_fn_ptr1.stderr index d048377a77..d758579000 100644 --- a/tests/fail/validity/cast_fn_ptr1.stderr +++ b/tests/fail/validity/cast_fn_ptr1.stderr @@ -1,3 +1,18 @@ +warning: pointer-to-integer cast + --> $DIR/cast_fn_ptr1.rs:LL:CC + | +LL | g(0usize as *const i32) + | ^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/cast_fn_ptr1.rs:LL:CC + error: Undefined Behavior: type validation failed: encountered a null reference --> $DIR/cast_fn_ptr1.rs:LL:CC | @@ -11,5 +26,5 @@ LL | g(0usize as *const i32) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/fail/validity/cast_fn_ptr2.stderr b/tests/fail/validity/cast_fn_ptr2.stderr index 10b9b9b860..d47b39356f 100644 --- a/tests/fail/validity/cast_fn_ptr2.stderr +++ b/tests/fail/validity/cast_fn_ptr2.stderr @@ -1,3 +1,23 @@ +warning: pointer-to-integer cast + --> $DIR/cast_fn_ptr2.rs:LL:CC + | +LL | 0usize as *const i32 + | ^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main::f` at $DIR/cast_fn_ptr2.rs:LL:CC +note: inside `main` at $DIR/cast_fn_ptr2.rs:LL:CC + --> $DIR/cast_fn_ptr2.rs:LL:CC + | +LL | let _x = g(); + | ^^^ + error: Undefined Behavior: type validation failed: encountered a null reference --> $DIR/cast_fn_ptr2.rs:LL:CC | @@ -11,5 +31,5 @@ LL | let _x = g(); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted diff --git a/tests/pass/adjacent-allocs.rs b/tests/pass/adjacent-allocs.rs index 509965fe4f..925430ae20 100644 --- a/tests/pass/adjacent-allocs.rs +++ b/tests/pass/adjacent-allocs.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + fn main() { // The slack between allocations is random. // Loop a few times to hit the zero-slack case. diff --git a/tests/pass/align.stderr b/tests/pass/align.stderr new file mode 100644 index 0000000000..9a15ec2cda --- /dev/null +++ b/tests/pass/align.stderr @@ -0,0 +1,20 @@ +warning: pointer-to-integer cast + --> $DIR/align.rs:LL:CC + | +LL | let u16_ptr = base_addr_aligned as *mut u16; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `manual_alignment` at $DIR/align.rs:LL:CC +note: inside `main` at $DIR/align.rs:LL:CC + --> $DIR/align.rs:LL:CC + | +LL | manual_alignment(); + | ^^^^^^^^^^^^^^^^^^ + diff --git a/tests/pass/box.rs b/tests/pass/box.rs index c2ecc37071..7bbe7be516 100644 --- a/tests/pass/box.rs +++ b/tests/pass/box.rs @@ -47,7 +47,7 @@ fn boxed_pair_to_vec() { struct Foo(u64); fn reinterstruct(box_pair: Box) -> Vec { let ref_pair = Box::leak(box_pair) as *mut PairFoo; - let ptr_foo = unsafe { &mut (*ref_pair).fst as *mut Foo }; + let ptr_foo = unsafe { std::ptr::addr_of_mut!((*ref_pair).fst) }; unsafe { Vec::from_raw_parts(ptr_foo, 2, 2) } } diff --git a/tests/pass/box.stderr b/tests/pass/box.stderr new file mode 100644 index 0000000000..eac98bf2d1 --- /dev/null +++ b/tests/pass/box.stderr @@ -0,0 +1,20 @@ +warning: pointer-to-integer cast + --> $DIR/box.rs:LL:CC + | +LL | let r2 = ((r as usize) + 0) as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `into_raw` at $DIR/box.rs:LL:CC +note: inside `main` at $DIR/box.rs:LL:CC + --> $DIR/box.rs:LL:CC + | +LL | into_raw(); + | ^^^^^^^^^^ + diff --git a/tests/pass/concurrency/tls_pthread_drop_order.rs b/tests/pass/concurrency/tls_pthread_drop_order.rs index 4d69449821..29c57bf49a 100644 --- a/tests/pass/concurrency/tls_pthread_drop_order.rs +++ b/tests/pass/concurrency/tls_pthread_drop_order.rs @@ -4,6 +4,7 @@ extern crate libc; use std::mem; +use std::ptr; pub type Key = libc::pthread_key_t; @@ -11,7 +12,7 @@ static mut RECORD: usize = 0; static mut KEYS: [Key; 2] = [0; 2]; static mut GLOBALS: [u64; 2] = [1, 0]; -static mut CANNARY: *mut u64 = 0 as *mut _; // this serves as a cannary: if TLS dtors are not run properly, this will not get deallocated, making the test fail. +static mut CANNARY: *mut u64 = ptr::null_mut(); // this serves as a cannary: if TLS dtors are not run properly, this will not get deallocated, making the test fail. pub unsafe fn create(dtor: Option) -> Key { let mut key = 0; @@ -30,7 +31,7 @@ pub fn record(r: usize) { } unsafe extern "C" fn dtor(ptr: *mut u64) { - assert!(CANNARY != 0 as *mut _); // make sure we do not get run too often + assert!(CANNARY != ptr::null_mut()); // make sure we do not get run too often let val = *ptr; let which_key = @@ -48,7 +49,7 @@ unsafe extern "C" fn dtor(ptr: *mut u64) { // The correct sequence is: First key 0, then key 1, then key 0. if RECORD == 0_1_0 { drop(Box::from_raw(CANNARY)); - CANNARY = 0 as *mut _; + CANNARY = ptr::null_mut(); } } diff --git a/tests/pass/extern_types.stderr b/tests/pass/extern_types.stderr new file mode 100644 index 0000000000..730a430425 --- /dev/null +++ b/tests/pass/extern_types.stderr @@ -0,0 +1,15 @@ +warning: pointer-to-integer cast + --> $DIR/extern_types.rs:LL:CC + | +LL | let x: &Foo = unsafe { &*(16 as *const Foo) }; + | ^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | + = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, + = help: which means that Miri might miss pointer bugs in this program + = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation + = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead + = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics + = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning + + = note: inside `main` at $DIR/extern_types.rs:LL:CC + diff --git a/tests/pass/intptrcast.rs b/tests/pass/intptrcast.rs index aafa90204f..a5e1d19652 100644 --- a/tests/pass/intptrcast.rs +++ b/tests/pass/intptrcast.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + // This strips provenance fn transmute_ptr_to_int(x: *const T) -> usize { unsafe { std::mem::transmute(x) } diff --git a/tests/pass/intrinsics.rs b/tests/pass/intrinsics.rs index 9e310082f3..0042872a3b 100644 --- a/tests/pass/intrinsics.rs +++ b/tests/pass/intrinsics.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmiri-permissive-provenance #![feature(core_intrinsics, const_raw_ptr_comparison)] #![feature(layout_for_ptr)] diff --git a/tests/pass/linux-getrandom-without-isolation.rs b/tests/pass/linux-getrandom-without-isolation.rs index ad1a1f27c7..56a5369947 100644 --- a/tests/pass/linux-getrandom-without-isolation.rs +++ b/tests/pass/linux-getrandom-without-isolation.rs @@ -3,13 +3,15 @@ #![feature(rustc_private)] extern crate libc; +use std::ptr; + fn main() { let mut buf = [0u8; 5]; unsafe { assert_eq!( libc::syscall( libc::SYS_getrandom, - 0 as *mut libc::c_void, + ptr::null_mut::(), 0 as libc::size_t, 0 as libc::c_uint, ), @@ -26,7 +28,7 @@ fn main() { ); assert_eq!( - libc::getrandom(0 as *mut libc::c_void, 0 as libc::size_t, 0 as libc::c_uint), + libc::getrandom(ptr::null_mut::(), 0 as libc::size_t, 0 as libc::c_uint), 0, ); assert_eq!( diff --git a/tests/pass/linux-getrandom.rs b/tests/pass/linux-getrandom.rs index 7d3f899f44..a3596e4c7a 100644 --- a/tests/pass/linux-getrandom.rs +++ b/tests/pass/linux-getrandom.rs @@ -2,13 +2,15 @@ #![feature(rustc_private)] extern crate libc; +use std::ptr; + fn main() { let mut buf = [0u8; 5]; unsafe { assert_eq!( libc::syscall( libc::SYS_getrandom, - 0 as *mut libc::c_void, + ptr::null_mut::(), 0 as libc::size_t, 0 as libc::c_uint, ), @@ -25,7 +27,7 @@ fn main() { ); assert_eq!( - libc::getrandom(0 as *mut libc::c_void, 0 as libc::size_t, 0 as libc::c_uint), + libc::getrandom(ptr::null_mut::(), 0 as libc::size_t, 0 as libc::c_uint), 0, ); assert_eq!( diff --git a/tests/pass/panic/catch_panic.rs b/tests/pass/panic/catch_panic.rs index 2fb00391cd..3979fb3b07 100644 --- a/tests/pass/panic/catch_panic.rs +++ b/tests/pass/panic/catch_panic.rs @@ -1,5 +1,5 @@ // We test the `align_offset` panic below, make sure we test the interpreter impl and not the "real" one. -// compile-flags: -Zmiri-symbolic-alignment-check +// compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance #![feature(never_type)] #![allow(unconditional_panic, non_fmt_panics)] diff --git a/tests/pass/ptr_int_casts.rs b/tests/pass/ptr_int_casts.rs index 889b6bd04f..ffe6a114c6 100644 --- a/tests/pass/ptr_int_casts.rs +++ b/tests/pass/ptr_int_casts.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmiri-permissive-provenance use std::mem; use std::ptr; diff --git a/tests/pass/ptr_offset.rs b/tests/pass/ptr_offset.rs index 1b25df7214..b16a06a726 100644 --- a/tests/pass/ptr_offset.rs +++ b/tests/pass/ptr_offset.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmiri-permissive-provenance use std::{mem, ptr}; fn main() { diff --git a/tests/pass/stacked-borrows/2phase.rs b/tests/pass/stacked-borrows/2phase.rs index 345cb64ccf..eb543d691e 100644 --- a/tests/pass/stacked-borrows/2phase.rs +++ b/tests/pass/stacked-borrows/2phase.rs @@ -1,5 +1,3 @@ -// compile-flags: -Zmiri-tag-raw-pointers - trait S: Sized { fn tpb(&mut self, _s: Self) {} } diff --git a/tests/pass/stacked-borrows/interior_mutability.rs b/tests/pass/stacked-borrows/interior_mutability.rs index 9ee8af45ae..79958ab553 100644 --- a/tests/pass/stacked-borrows/interior_mutability.rs +++ b/tests/pass/stacked-borrows/interior_mutability.rs @@ -1,4 +1,3 @@ -// compile-flags: -Zmiri-tag-raw-pointers use std::cell::{Cell, RefCell, UnsafeCell}; use std::mem::{self, MaybeUninit}; diff --git a/tests/pass/stacked-borrows/stacked-borrows.rs b/tests/pass/stacked-borrows/stacked-borrows.rs index 131783ef4f..eb0ff167eb 100644 --- a/tests/pass/stacked-borrows/stacked-borrows.rs +++ b/tests/pass/stacked-borrows/stacked-borrows.rs @@ -1,4 +1,3 @@ -// compile-flags: -Zmiri-tag-raw-pointers use std::ptr; // Test various stacked-borrows-related things. diff --git a/tests/pass/zst.rs b/tests/pass/zst.rs index 3a853e7d8a..fade1e0dad 100644 --- a/tests/pass/zst.rs +++ b/tests/pass/zst.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zmiri-permissive-provenance #[derive(PartialEq, Debug)] struct A; From 294ef15adbf6b4778a8eb638b31a48744914ec0a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 21:26:14 -0400 Subject: [PATCH 02/10] more int2ptr cast tests, and fix casting of addresses inside dead allocations --- src/intptrcast.rs | 12 +++++++-- tests/fail/backtrace/bad-backtrace-flags.rs | 2 +- .../fail/backtrace/bad-backtrace-flags.stderr | 21 +++------------ tests/fail/backtrace/bad-backtrace-ptr.rs | 2 +- tests/fail/backtrace/bad-backtrace-ptr.stderr | 21 +++------------ .../backtrace/bad-backtrace-resolve-flags.rs | 2 +- .../bad-backtrace-resolve-flags.stderr | 17 +----------- .../bad-backtrace-resolve-names-flags.rs | 4 +-- .../bad-backtrace-resolve-names-flags.stderr | 21 +++------------ .../thread_local_static_dealloc.rs | 7 +++-- .../thread_local_static_dealloc.stderr | 21 +++------------ .../dangling_pointers/deref-invalid-ptr.rs | 2 +- .../deref-invalid-ptr.stderr | 17 +----------- .../storage_dead_dangling.rs | 6 ++--- .../storage_dead_dangling.stderr | 26 +++--------------- .../dangling_pointers/wild_pointer_deref.rs | 2 ++ .../wild_pointer_deref.stderr | 17 +----------- tests/fail/intrinsics/ptr_offset_0_plus_0.rs | 1 + .../intrinsics/ptr_offset_0_plus_0.stderr | 17 +----------- .../intrinsics/ptr_offset_int_plus_int.rs | 1 + .../intrinsics/ptr_offset_int_plus_int.stderr | 17 +----------- .../intrinsics/ptr_offset_int_plus_ptr.rs | 1 + .../intrinsics/ptr_offset_int_plus_ptr.stderr | 17 +----------- .../permissive_provenance_transmute.stderr | 20 -------------- ...e_transmute.rs => provenance_transmute.rs} | 0 ...ute.stderr => provenance_transmute.stderr} | 8 +++--- .../fail/provenance/strict_provenance_cast.rs | 6 +++++ .../provenance/strict_provenance_cast.stderr | 14 ++++++++++ .../provenance/strict_provenance_transmute.rs | 27 ------------------- tests/fail/stacked_borrows/unescaped_local.rs | 2 ++ .../stacked_borrows/unescaped_local.stderr | 17 +----------- .../intptrcast_alignment_check.rs | 2 +- .../intptrcast_alignment_check.stderr | 17 +----------- tests/fail/validity/cast_fn_ptr1.rs | 2 ++ tests/fail/validity/cast_fn_ptr1.stderr | 17 +----------- tests/fail/validity/cast_fn_ptr2.rs | 2 ++ tests/fail/validity/cast_fn_ptr2.stderr | 22 +-------------- tests/pass/adjacent-allocs.rs | 27 +++++++++++++++++-- tests/pass/align.rs | 2 ++ tests/pass/align.stderr | 20 -------------- tests/pass/intptrcast.rs | 11 ++++++++ 41 files changed, 123 insertions(+), 347 deletions(-) delete mode 100644 tests/fail/provenance/permissive_provenance_transmute.stderr rename tests/fail/provenance/{permissive_provenance_transmute.rs => provenance_transmute.rs} (100%) rename tests/fail/provenance/{strict_provenance_transmute.stderr => provenance_transmute.stderr} (75%) create mode 100644 tests/fail/provenance/strict_provenance_cast.rs create mode 100644 tests/fail/provenance/strict_provenance_cast.stderr delete mode 100644 tests/fail/provenance/strict_provenance_transmute.rs delete mode 100644 tests/pass/align.stderr diff --git a/src/intptrcast.rs b/src/intptrcast.rs index c92954a218..cb0d6517b9 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -90,8 +90,16 @@ impl<'mir, 'tcx> GlobalStateInner { } }?; - // We only use this provenance if it has been exposed. - if global_state.exposed.contains(&alloc_id) { Some(alloc_id) } else { None } + // We only use this provenance if it has been exposed, *and* is still live. + if global_state.exposed.contains(&alloc_id) { + // FIXME: this catches `InterpError`, which we should not usually do. + // We might need a proper fallible API from `memory.rs` to avoid this though. + if let Ok(_) = ecx.get_alloc_size_and_align(alloc_id, AllocCheck::Live) { + return Some(alloc_id); + } + } + + None } pub fn expose_ptr(ecx: &mut MiriEvalContext<'mir, 'tcx>, alloc_id: AllocId, sb: SbTag) { diff --git a/tests/fail/backtrace/bad-backtrace-flags.rs b/tests/fail/backtrace/bad-backtrace-flags.rs index 5f30513e93..9e24d32a33 100644 --- a/tests/fail/backtrace/bad-backtrace-flags.rs +++ b/tests/fail/backtrace/bad-backtrace-flags.rs @@ -4,6 +4,6 @@ extern "Rust" { fn main() { unsafe { - miri_get_backtrace(2, 0 as *mut _); //~ ERROR unsupported operation: unknown `miri_get_backtrace` flags 2 + miri_get_backtrace(2, std::ptr::null_mut()); //~ ERROR unsupported operation: unknown `miri_get_backtrace` flags 2 } } diff --git a/tests/fail/backtrace/bad-backtrace-flags.stderr b/tests/fail/backtrace/bad-backtrace-flags.stderr index ba16335fce..6d62ffc00e 100644 --- a/tests/fail/backtrace/bad-backtrace-flags.stderr +++ b/tests/fail/backtrace/bad-backtrace-flags.stderr @@ -1,23 +1,8 @@ -warning: pointer-to-integer cast - --> $DIR/bad-backtrace-flags.rs:LL:CC - | -LL | miri_get_backtrace(2, 0 as *mut _); - | ^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/bad-backtrace-flags.rs:LL:CC - error: unsupported operation: unknown `miri_get_backtrace` flags 2 --> $DIR/bad-backtrace-flags.rs:LL:CC | -LL | miri_get_backtrace(2, 0 as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_get_backtrace` flags 2 +LL | miri_get_backtrace(2, std::ptr::null_mut()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_get_backtrace` flags 2 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support @@ -25,5 +10,5 @@ LL | miri_get_backtrace(2, 0 as *mut _); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/backtrace/bad-backtrace-ptr.rs b/tests/fail/backtrace/bad-backtrace-ptr.rs index c83bf1eb38..73d3561445 100644 --- a/tests/fail/backtrace/bad-backtrace-ptr.rs +++ b/tests/fail/backtrace/bad-backtrace-ptr.rs @@ -4,6 +4,6 @@ extern "Rust" { fn main() { unsafe { - miri_resolve_frame(0 as *mut _, 0); //~ ERROR null pointer is not a valid pointer for this operation + miri_resolve_frame(std::ptr::null_mut(), 0); //~ ERROR null pointer is not a valid pointer for this operation } } diff --git a/tests/fail/backtrace/bad-backtrace-ptr.stderr b/tests/fail/backtrace/bad-backtrace-ptr.stderr index 75268b6671..6911db9de0 100644 --- a/tests/fail/backtrace/bad-backtrace-ptr.stderr +++ b/tests/fail/backtrace/bad-backtrace-ptr.stderr @@ -1,23 +1,8 @@ -warning: pointer-to-integer cast - --> $DIR/bad-backtrace-ptr.rs:LL:CC - | -LL | miri_resolve_frame(0 as *mut _, 0); - | ^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/bad-backtrace-ptr.rs:LL:CC - error: Undefined Behavior: null pointer is not a valid pointer for this operation --> $DIR/bad-backtrace-ptr.rs:LL:CC | -LL | miri_resolve_frame(0 as *mut _, 0); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation +LL | miri_resolve_frame(std::ptr::null_mut(), 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ null pointer is not a valid pointer for this operation | = 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 @@ -26,5 +11,5 @@ LL | miri_resolve_frame(0 as *mut _, 0); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/backtrace/bad-backtrace-resolve-flags.rs b/tests/fail/backtrace/bad-backtrace-resolve-flags.rs index 5a30253a89..2d4d619502 100644 --- a/tests/fail/backtrace/bad-backtrace-resolve-flags.rs +++ b/tests/fail/backtrace/bad-backtrace-resolve-flags.rs @@ -15,7 +15,7 @@ extern "Rust" { fn main() { unsafe { - let mut buf = vec![0 as *mut _; miri_backtrace_size(0)]; + let mut buf = vec![std::ptr::null_mut(); miri_backtrace_size(0)]; miri_get_backtrace(1, buf.as_mut_ptr()); diff --git a/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr b/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr index fad9ffe119..49495651df 100644 --- a/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr +++ b/tests/fail/backtrace/bad-backtrace-resolve-flags.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/bad-backtrace-resolve-flags.rs:LL:CC - | -LL | let mut buf = vec![0 as *mut _; miri_backtrace_size(0)]; - | ^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/bad-backtrace-resolve-flags.rs:LL:CC - error: unsupported operation: unknown `miri_resolve_frame` flags 2 --> $DIR/bad-backtrace-resolve-flags.rs:LL:CC | @@ -25,5 +10,5 @@ LL | miri_resolve_frame(buf[0], 2); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/backtrace/bad-backtrace-resolve-names-flags.rs b/tests/fail/backtrace/bad-backtrace-resolve-names-flags.rs index 8e69a27575..6cea1fec1b 100644 --- a/tests/fail/backtrace/bad-backtrace-resolve-names-flags.rs +++ b/tests/fail/backtrace/bad-backtrace-resolve-names-flags.rs @@ -6,11 +6,11 @@ extern "Rust" { fn main() { unsafe { - let mut buf = vec![0 as *mut _; miri_backtrace_size(0)]; + let mut buf = vec![std::ptr::null_mut(); miri_backtrace_size(0)]; miri_get_backtrace(1, buf.as_mut_ptr()); // miri_resolve_frame_names will error from an invalid backtrace before it will from invalid flags - miri_resolve_frame_names(buf[0], 2, 0 as *mut _, 0 as *mut _); //~ ERROR unsupported operation: unknown `miri_resolve_frame_names` flags 2 + miri_resolve_frame_names(buf[0], 2, std::ptr::null_mut(), std::ptr::null_mut()); //~ ERROR unsupported operation: unknown `miri_resolve_frame_names` flags 2 } } diff --git a/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr b/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr index 18b03df21c..aa470cb9de 100644 --- a/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr +++ b/tests/fail/backtrace/bad-backtrace-resolve-names-flags.stderr @@ -1,23 +1,8 @@ -warning: pointer-to-integer cast - --> $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC - | -LL | let mut buf = vec![0 as *mut _; miri_backtrace_size(0)]; - | ^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC - error: unsupported operation: unknown `miri_resolve_frame_names` flags 2 --> $DIR/bad-backtrace-resolve-names-flags.rs:LL:CC | -LL | ... miri_resolve_frame_names(buf[0], 2, 0 as *mut _, 0 as *mut _); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_resolve_frame_names` flags 2 +LL | ... miri_resolve_frame_names(buf[0], 2, std::ptr::null_mut(), std::ptr::null_mut()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unknown `miri_resolve_frame_names` flags 2 | = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support @@ -25,5 +10,5 @@ LL | ... miri_resolve_frame_names(buf[0], 2, 0 as *mut _, 0 as *mut _); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/concurrency/thread_local_static_dealloc.rs b/tests/fail/concurrency/thread_local_static_dealloc.rs index d5a4bf27f8..e6031b5e4c 100644 --- a/tests/fail/concurrency/thread_local_static_dealloc.rs +++ b/tests/fail/concurrency/thread_local_static_dealloc.rs @@ -7,9 +7,12 @@ #[thread_local] static mut TLS: u8 = 0; +struct SendRaw(*const u8); +unsafe impl Send for SendRaw {} + fn main() { unsafe { - let dangling_ptr = std::thread::spawn(|| &TLS as *const u8 as usize).join().unwrap(); - let _val = *(dangling_ptr as *const u8); //~ ERROR dereferenced after this allocation got freed + let dangling_ptr = std::thread::spawn(|| SendRaw(&TLS as *const u8)).join().unwrap(); + let _val = *dangling_ptr.0; //~ ERROR dereferenced after this allocation got freed } } diff --git a/tests/fail/concurrency/thread_local_static_dealloc.stderr b/tests/fail/concurrency/thread_local_static_dealloc.stderr index 31a64eec36..d54c569de3 100644 --- a/tests/fail/concurrency/thread_local_static_dealloc.stderr +++ b/tests/fail/concurrency/thread_local_static_dealloc.stderr @@ -1,23 +1,8 @@ -warning: pointer-to-integer cast - --> $DIR/thread_local_static_dealloc.rs:LL:CC - | -LL | let _val = *(dangling_ptr as *const u8); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/thread_local_static_dealloc.rs:LL:CC - error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed --> $DIR/thread_local_static_dealloc.rs:LL:CC | -LL | let _val = *(dangling_ptr as *const u8); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed +LL | let _val = *dangling_ptr.0; + | ^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed | = 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 @@ -26,5 +11,5 @@ LL | let _val = *(dangling_ptr as *const u8); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/dangling_pointers/deref-invalid-ptr.rs b/tests/fail/dangling_pointers/deref-invalid-ptr.rs index 56830e97ca..cb2bbec8bc 100644 --- a/tests/fail/dangling_pointers/deref-invalid-ptr.rs +++ b/tests/fail/dangling_pointers/deref-invalid-ptr.rs @@ -1,5 +1,5 @@ // This should fail even without validation. -// compile-flags: -Zmiri-disable-validation +// compile-flags: -Zmiri-disable-validation -Zmiri-permissive-provenance fn main() { let x = 16usize as *const u32; diff --git a/tests/fail/dangling_pointers/deref-invalid-ptr.stderr b/tests/fail/dangling_pointers/deref-invalid-ptr.stderr index ffd7fb1980..f4361d9fef 100644 --- a/tests/fail/dangling_pointers/deref-invalid-ptr.stderr +++ b/tests/fail/dangling_pointers/deref-invalid-ptr.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/deref-invalid-ptr.rs:LL:CC - | -LL | let x = 16usize as *const u32; - | ^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/deref-invalid-ptr.rs:LL:CC - error: Undefined Behavior: dereferencing pointer failed: 0x10 is not a valid pointer --> $DIR/deref-invalid-ptr.rs:LL:CC | @@ -26,5 +11,5 @@ LL | let _y = unsafe { &*x as *const u32 }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/dangling_pointers/storage_dead_dangling.rs b/tests/fail/dangling_pointers/storage_dead_dangling.rs index c87db4b022..370162142d 100644 --- a/tests/fail/dangling_pointers/storage_dead_dangling.rs +++ b/tests/fail/dangling_pointers/storage_dead_dangling.rs @@ -1,5 +1,5 @@ // This should fail even without validation, but some MIR opts mask the error -// compile-flags: -Zmiri-disable-validation -Zmir-opt-level=0 +// compile-flags: -Zmiri-disable-validation -Zmir-opt-level=0 -Zmiri-permissive-provenance static mut LEAK: usize = 0; @@ -10,7 +10,7 @@ fn fill(v: &mut i32) { } fn evil() { - unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR dereferenced after this allocation got freed + unsafe { &mut *(LEAK as *mut i32) }; //~ ERROR is not a valid pointer } fn main() { @@ -21,6 +21,6 @@ fn main() { _y = x; } // Now we use a pointer to `x` which is no longer in scope, and thus dead (even though the - // `main` stack frame still exists). + // `main` stack frame still exists). We even try going through a `usize` for extra sneakiness! evil(); } diff --git a/tests/fail/dangling_pointers/storage_dead_dangling.stderr b/tests/fail/dangling_pointers/storage_dead_dangling.stderr index 3a94a7fa58..d6030643bf 100644 --- a/tests/fail/dangling_pointers/storage_dead_dangling.stderr +++ b/tests/fail/dangling_pointers/storage_dead_dangling.stderr @@ -1,28 +1,8 @@ -warning: pointer-to-integer cast +error: Undefined Behavior: dereferencing pointer failed: $HEX is not a valid pointer --> $DIR/storage_dead_dangling.rs:LL:CC | LL | unsafe { &mut *(LEAK as *mut i32) }; - | ^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `evil` at $DIR/storage_dead_dangling.rs:LL:CC -note: inside `main` at $DIR/storage_dead_dangling.rs:LL:CC - --> $DIR/storage_dead_dangling.rs:LL:CC - | -LL | evil(); - | ^^^^^^ - -error: Undefined Behavior: pointer to ALLOC was dereferenced after this allocation got freed - --> $DIR/storage_dead_dangling.rs:LL:CC - | -LL | unsafe { &mut *(LEAK as *mut i32) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^ pointer to ALLOC was dereferenced after this allocation got freed + | ^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: $HEX is not a valid pointer | = 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 @@ -36,5 +16,5 @@ LL | evil(); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/dangling_pointers/wild_pointer_deref.rs b/tests/fail/dangling_pointers/wild_pointer_deref.rs index eebaea48ba..7c9f5281fb 100644 --- a/tests/fail/dangling_pointers/wild_pointer_deref.rs +++ b/tests/fail/dangling_pointers/wild_pointer_deref.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + fn main() { let p = 44 as *const i32; let x = unsafe { *p }; //~ ERROR is not a valid pointer diff --git a/tests/fail/dangling_pointers/wild_pointer_deref.stderr b/tests/fail/dangling_pointers/wild_pointer_deref.stderr index 960f9c9ce3..b20f310da0 100644 --- a/tests/fail/dangling_pointers/wild_pointer_deref.stderr +++ b/tests/fail/dangling_pointers/wild_pointer_deref.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/wild_pointer_deref.rs:LL:CC - | -LL | let p = 44 as *const i32; - | ^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/wild_pointer_deref.rs:LL:CC - error: Undefined Behavior: dereferencing pointer failed: 0x2c is not a valid pointer --> $DIR/wild_pointer_deref.rs:LL:CC | @@ -26,5 +11,5 @@ LL | let x = unsafe { *p }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/intrinsics/ptr_offset_0_plus_0.rs b/tests/fail/intrinsics/ptr_offset_0_plus_0.rs index 248d85d65e..ca38f39d25 100644 --- a/tests/fail/intrinsics/ptr_offset_0_plus_0.rs +++ b/tests/fail/intrinsics/ptr_offset_0_plus_0.rs @@ -1,4 +1,5 @@ // error-pattern: pointer arithmetic failed: null pointer is not a valid pointer +// compile-flags: -Zmiri-permissive-provenance fn main() { let x = 0 as *mut i32; diff --git a/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr b/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr index 2474820545..741314ea8a 100644 --- a/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr +++ b/tests/fail/intrinsics/ptr_offset_0_plus_0.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/ptr_offset_0_plus_0.rs:LL:CC - | -LL | let x = 0 as *mut i32; - | ^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/ptr_offset_0_plus_0.rs:LL:CC - error: Undefined Behavior: pointer arithmetic failed: null pointer is not a valid pointer --> RUSTLIB/core/src/ptr/mut_ptr.rs:LL:CC | @@ -31,5 +16,5 @@ LL | let _x = unsafe { x.offset(0) }; // UB despite offset 0, NULL is never note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/intrinsics/ptr_offset_int_plus_int.rs b/tests/fail/intrinsics/ptr_offset_int_plus_int.rs index e332a9dc62..809938d999 100644 --- a/tests/fail/intrinsics/ptr_offset_int_plus_int.rs +++ b/tests/fail/intrinsics/ptr_offset_int_plus_int.rs @@ -1,4 +1,5 @@ // error-pattern: is not a valid pointer +// compile-flags: -Zmiri-permissive-provenance fn main() { // Can't offset an integer pointer by non-zero offset. diff --git a/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr b/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr index f5cbd4bbbf..e6b8f102f3 100644 --- a/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr +++ b/tests/fail/intrinsics/ptr_offset_int_plus_int.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/ptr_offset_int_plus_int.rs:LL:CC - | -LL | let _val = (1 as *mut u8).offset(1); - | ^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/ptr_offset_int_plus_int.rs:LL:CC - error: Undefined Behavior: pointer arithmetic failed: 0x1 is not a valid pointer --> RUSTLIB/core/src/ptr/mut_ptr.rs:LL:CC | @@ -31,5 +16,5 @@ LL | let _val = (1 as *mut u8).offset(1); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/intrinsics/ptr_offset_int_plus_ptr.rs b/tests/fail/intrinsics/ptr_offset_int_plus_ptr.rs index 2d27e25a7a..903f89ff70 100644 --- a/tests/fail/intrinsics/ptr_offset_int_plus_ptr.rs +++ b/tests/fail/intrinsics/ptr_offset_int_plus_ptr.rs @@ -1,4 +1,5 @@ // error-pattern: is not a valid pointer +// compile-flags: -Zmiri-permissive-provenance fn main() { let ptr = Box::into_raw(Box::new(0u32)); diff --git a/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr b/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr index 577a377f07..f88ad758d4 100644 --- a/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr +++ b/tests/fail/intrinsics/ptr_offset_int_plus_ptr.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/ptr_offset_int_plus_ptr.rs:LL:CC - | -LL | let _val = (1 as *mut u8).offset(ptr as isize); - | ^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/ptr_offset_int_plus_ptr.rs:LL:CC - error: Undefined Behavior: pointer arithmetic failed: 0x1 is not a valid pointer --> RUSTLIB/core/src/ptr/mut_ptr.rs:LL:CC | @@ -31,5 +16,5 @@ LL | let _val = (1 as *mut u8).offset(ptr as isize); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/provenance/permissive_provenance_transmute.stderr b/tests/fail/provenance/permissive_provenance_transmute.stderr deleted file mode 100644 index 12f3562011..0000000000 --- a/tests/fail/provenance/permissive_provenance_transmute.stderr +++ /dev/null @@ -1,20 +0,0 @@ -error: Undefined Behavior: dereferencing pointer failed: $HEX is not a valid pointer - --> $DIR/permissive_provenance_transmute.rs:LL:CC - | -LL | let _val = *left_ptr; - | ^^^^^^^^^ dereferencing pointer failed: $HEX is not a valid pointer - | - = 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: inside `deref` at $DIR/permissive_provenance_transmute.rs:LL:CC -note: inside `main` at $DIR/permissive_provenance_transmute.rs:LL:CC - --> $DIR/permissive_provenance_transmute.rs:LL:CC - | -LL | deref(ptr1, ptr2.with_addr(ptr1.addr())); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -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/provenance/permissive_provenance_transmute.rs b/tests/fail/provenance/provenance_transmute.rs similarity index 100% rename from tests/fail/provenance/permissive_provenance_transmute.rs rename to tests/fail/provenance/provenance_transmute.rs diff --git a/tests/fail/provenance/strict_provenance_transmute.stderr b/tests/fail/provenance/provenance_transmute.stderr similarity index 75% rename from tests/fail/provenance/strict_provenance_transmute.stderr rename to tests/fail/provenance/provenance_transmute.stderr index 8df94d50bb..9cbec077e4 100644 --- a/tests/fail/provenance/strict_provenance_transmute.stderr +++ b/tests/fail/provenance/provenance_transmute.stderr @@ -1,5 +1,5 @@ error: Undefined Behavior: dereferencing pointer failed: $HEX is not a valid pointer - --> $DIR/strict_provenance_transmute.rs:LL:CC + --> $DIR/provenance_transmute.rs:LL:CC | LL | let _val = *left_ptr; | ^^^^^^^^^ dereferencing pointer failed: $HEX is not a valid pointer @@ -7,9 +7,9 @@ LL | let _val = *left_ptr; = 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: inside `deref` at $DIR/strict_provenance_transmute.rs:LL:CC -note: inside `main` at $DIR/strict_provenance_transmute.rs:LL:CC - --> $DIR/strict_provenance_transmute.rs:LL:CC + = note: inside `deref` at $DIR/provenance_transmute.rs:LL:CC +note: inside `main` at $DIR/provenance_transmute.rs:LL:CC + --> $DIR/provenance_transmute.rs:LL:CC | LL | deref(ptr1, ptr2.with_addr(ptr1.addr())); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/tests/fail/provenance/strict_provenance_cast.rs b/tests/fail/provenance/strict_provenance_cast.rs new file mode 100644 index 0000000000..8b2b053bdb --- /dev/null +++ b/tests/fail/provenance/strict_provenance_cast.rs @@ -0,0 +1,6 @@ +// compile-flags: -Zmiri-strict-provenance + +fn main() { + let addr = &0 as *const i32 as usize; + let _ptr = addr as *const i32; //~ ERROR integer-to-pointer casts and `from_exposed_addr` are not supported +} diff --git a/tests/fail/provenance/strict_provenance_cast.stderr b/tests/fail/provenance/strict_provenance_cast.stderr new file mode 100644 index 0000000000..32a39b81d9 --- /dev/null +++ b/tests/fail/provenance/strict_provenance_cast.stderr @@ -0,0 +1,14 @@ +error: unsupported operation: integer-to-pointer casts and `from_exposed_addr` are not supported with `-Zmiri-strict-provenance`; use `with_addr` instead + --> $DIR/strict_provenance_cast.rs:LL:CC + | +LL | let _ptr = addr as *const i32; + | ^^^^^^^^^^^^^^^^^^ integer-to-pointer casts and `from_exposed_addr` are not supported with `-Zmiri-strict-provenance`; use `with_addr` instead + | + = help: this is likely not a bug in the program; it indicates that the program performed an operation that the interpreter does not support + + = note: inside `main` at $DIR/strict_provenance_cast.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/provenance/strict_provenance_transmute.rs b/tests/fail/provenance/strict_provenance_transmute.rs deleted file mode 100644 index 12a141e9dd..0000000000 --- a/tests/fail/provenance/strict_provenance_transmute.rs +++ /dev/null @@ -1,27 +0,0 @@ -// compile-flags: -Zmiri-strict-provenance -#![feature(strict_provenance)] - -use std::mem; - -// This is the example from -// . - -unsafe fn deref(left: *const u8, right: *const u8) { - let left_int: usize = mem::transmute(left); - let right_int: usize = mem::transmute(right); - if left_int == right_int { - // 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 - } -} - -fn main() { - let ptr1 = &0u8 as *const u8; - let ptr2 = &1u8 as *const u8; - unsafe { - // Two pointers with the same address but different provenance. - deref(ptr1, ptr2.with_addr(ptr1.addr())); - } -} diff --git a/tests/fail/stacked_borrows/unescaped_local.rs b/tests/fail/stacked_borrows/unescaped_local.rs index bfc937bb12..c994f6c381 100644 --- a/tests/fail/stacked_borrows/unescaped_local.rs +++ b/tests/fail/stacked_borrows/unescaped_local.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + // Make sure we cannot use raw ptrs to access a local that // we took the direct address of. fn main() { diff --git a/tests/fail/stacked_borrows/unescaped_local.stderr b/tests/fail/stacked_borrows/unescaped_local.stderr index 2f6605c058..464296651c 100644 --- a/tests/fail/stacked_borrows/unescaped_local.stderr +++ b/tests/fail/stacked_borrows/unescaped_local.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/unescaped_local.rs:LL:CC - | -LL | let raw = &mut x as *mut i32 as usize as *mut i32; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/unescaped_local.rs:LL:CC - error: Undefined Behavior: attempting a write access using at ALLOC[0x0], but no exposed tags have suitable permission in the borrow stack for this location --> $DIR/unescaped_local.rs:LL:CC | @@ -29,5 +14,5 @@ LL | *raw = 13; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +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 0a326a453e..dea9335ab7 100644 --- a/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs +++ b/tests/fail/unaligned_pointers/intptrcast_alignment_check.rs @@ -1,4 +1,4 @@ -// compile-flags: -Zmiri-symbolic-alignment-check +// compile-flags: -Zmiri-symbolic-alignment-check -Zmiri-permissive-provenance // With the symbolic alignment check, even with intptrcast and without // validation, we want to be *sure* to catch bugs that arise from pointers being // insufficiently aligned. The only way to achieve that is not not let programs diff --git a/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr b/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr index bd8d161de8..347486187e 100644 --- a/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr +++ b/tests/fail/unaligned_pointers/intptrcast_alignment_check.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/intptrcast_alignment_check.rs:LL:CC - | -LL | let u16_ptr = base_addr_aligned as *mut u16; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/intptrcast_alignment_check.rs:LL:CC - error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required --> $DIR/intptrcast_alignment_check.rs:LL:CC | @@ -26,5 +11,5 @@ LL | unsafe { *u16_ptr = 2 }; note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/validity/cast_fn_ptr1.rs b/tests/fail/validity/cast_fn_ptr1.rs index 020e7be34f..eb5774fe79 100644 --- a/tests/fail/validity/cast_fn_ptr1.rs +++ b/tests/fail/validity/cast_fn_ptr1.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + fn main() { // Cast a function pointer such that on a call, the argument gets transmuted // from raw ptr to reference. This is ABI-compatible, so it's not the call that diff --git a/tests/fail/validity/cast_fn_ptr1.stderr b/tests/fail/validity/cast_fn_ptr1.stderr index d758579000..d048377a77 100644 --- a/tests/fail/validity/cast_fn_ptr1.stderr +++ b/tests/fail/validity/cast_fn_ptr1.stderr @@ -1,18 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/cast_fn_ptr1.rs:LL:CC - | -LL | g(0usize as *const i32) - | ^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main` at $DIR/cast_fn_ptr1.rs:LL:CC - error: Undefined Behavior: type validation failed: encountered a null reference --> $DIR/cast_fn_ptr1.rs:LL:CC | @@ -26,5 +11,5 @@ LL | g(0usize as *const i32) note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/fail/validity/cast_fn_ptr2.rs b/tests/fail/validity/cast_fn_ptr2.rs index 10fc39f56f..1cf4ca7d19 100644 --- a/tests/fail/validity/cast_fn_ptr2.rs +++ b/tests/fail/validity/cast_fn_ptr2.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + fn main() { // Cast a function pointer such that when returning, the return value gets transmuted // from raw ptr to reference. This is ABI-compatible, so it's not the call that diff --git a/tests/fail/validity/cast_fn_ptr2.stderr b/tests/fail/validity/cast_fn_ptr2.stderr index d47b39356f..10b9b9b860 100644 --- a/tests/fail/validity/cast_fn_ptr2.stderr +++ b/tests/fail/validity/cast_fn_ptr2.stderr @@ -1,23 +1,3 @@ -warning: pointer-to-integer cast - --> $DIR/cast_fn_ptr2.rs:LL:CC - | -LL | 0usize as *const i32 - | ^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `main::f` at $DIR/cast_fn_ptr2.rs:LL:CC -note: inside `main` at $DIR/cast_fn_ptr2.rs:LL:CC - --> $DIR/cast_fn_ptr2.rs:LL:CC - | -LL | let _x = g(); - | ^^^ - error: Undefined Behavior: type validation failed: encountered a null reference --> $DIR/cast_fn_ptr2.rs:LL:CC | @@ -31,5 +11,5 @@ LL | let _x = g(); note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace -error: aborting due to previous error; 1 warning emitted +error: aborting due to previous error diff --git a/tests/pass/adjacent-allocs.rs b/tests/pass/adjacent-allocs.rs index 925430ae20..b3483a5b43 100644 --- a/tests/pass/adjacent-allocs.rs +++ b/tests/pass/adjacent-allocs.rs @@ -1,9 +1,9 @@ // compile-flags: -Zmiri-permissive-provenance -fn main() { +fn test1() { // The slack between allocations is random. // Loop a few times to hit the zero-slack case. - for _ in 0..1024 { + for _ in 0..512 { let n = 0u64; let ptr: *const u64 = &n; @@ -22,3 +22,26 @@ fn main() { unsafe { *zst } } } + +fn test2() { + fn foo() -> u64 { + 0 + } + + for _ in 0..512 { + let n = 0u64; + let ptr: *const u64 = &n; + foo(); + let iptr = ptr as usize; + unsafe { + let start = &*std::ptr::slice_from_raw_parts(iptr as *const (), 1); + let end = &*std::ptr::slice_from_raw_parts((iptr + 8) as *const (), 1); + assert_eq!(start.len(), end.len()); + } + } +} + +fn main() { + test1(); + test2(); +} diff --git a/tests/pass/align.rs b/tests/pass/align.rs index 5794b7f542..f412541bde 100644 --- a/tests/pass/align.rs +++ b/tests/pass/align.rs @@ -1,3 +1,5 @@ +// compile-flags: -Zmiri-permissive-provenance + /// This manually makes sure that we have a pointer with the proper alignment. fn manual_alignment() { let x = &mut [0u8; 3]; diff --git a/tests/pass/align.stderr b/tests/pass/align.stderr deleted file mode 100644 index 9a15ec2cda..0000000000 --- a/tests/pass/align.stderr +++ /dev/null @@ -1,20 +0,0 @@ -warning: pointer-to-integer cast - --> $DIR/align.rs:LL:CC - | -LL | let u16_ptr = base_addr_aligned as *mut u16; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast - | - = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, - = help: which means that Miri might miss pointer bugs in this program - = help: see https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html for more details on that operation - = help: to ensure that Miri does not miss bugs in your program, use `with_addr` (https://doc.rust-lang.org/nightly/std/ptr/index.html#strict-provenance) instead - = help: you can then pass the `-Zmiri-strict-provenance` flag to Miri, to ensure you are not relying on `from_exposed_addr` semantics - = help: alternatively, the `-Zmiri-permissive-provenance` flag disables this warning - - = note: inside `manual_alignment` at $DIR/align.rs:LL:CC -note: inside `main` at $DIR/align.rs:LL:CC - --> $DIR/align.rs:LL:CC - | -LL | manual_alignment(); - | ^^^^^^^^^^^^^^^^^^ - diff --git a/tests/pass/intptrcast.rs b/tests/pass/intptrcast.rs index a5e1d19652..2417a83493 100644 --- a/tests/pass/intptrcast.rs +++ b/tests/pass/intptrcast.rs @@ -90,6 +90,16 @@ fn ptr_eq_integer() { assert!(x != 64 as *const i32); } +fn zst_deref_of_dangling() { + let b = Box::new(0); + let addr = &*b as *const _ as usize; + drop(b); + // Now if we cast `addr` to a ptr it might pick up the dangling provenance. + // But if we only do a ZST deref there is no UB here! + let zst = addr as *const (); + let _val = unsafe { *zst }; +} + fn main() { cast(); cast_dangling(); @@ -101,4 +111,5 @@ fn main() { ptr_eq_out_of_bounds(); ptr_eq_out_of_bounds_null(); ptr_eq_integer(); + zst_deref_of_dangling(); } From 5c16713056ceb866c89bb94c344285dee87d9d0d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 22:01:03 -0400 Subject: [PATCH 03/10] remove support for untagged pointers good riddance! --- src/bin/miri.rs | 2 +- src/diagnostics.rs | 18 ---- src/eval.rs | 2 +- src/lib.rs | 2 +- src/machine.rs | 8 +- src/stacked_borrows.rs | 165 +++++++++-------------------- src/stacked_borrows/diagnostics.rs | 94 +++------------- 7 files changed, 74 insertions(+), 217 deletions(-) diff --git a/src/bin/miri.rs b/src/bin/miri.rs index 7bced91264..a56b4bc6d1 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -409,7 +409,7 @@ fn main() { err ), }; - for id in ids.into_iter().map(miri::PtrId::new) { + for id in ids.into_iter().map(miri::SbTag::new) { if let Some(id) = id { miri_config.tracked_pointer_tags.insert(id); } else { diff --git a/src/diagnostics.rs b/src/diagnostics.rs index d17d1e6ed4..8176e51338 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -178,24 +178,6 @@ pub fn report_error<'tcx, 'mir>( helps.push((Some(*protection_span), "this protector is live for this call".to_string())); } } - Some(TagHistory::Untagged{ recently_created, recently_invalidated, matching_created, protected }) => { - if let Some((range, span)) = recently_created { - let msg = format!("tag was most recently created at offsets {}", HexRange(*range)); - helps.push((Some(*span), msg)); - } - if let Some((range, span)) = recently_invalidated { - let msg = format!("tag was later invalidated at offsets {}", HexRange(*range)); - helps.push((Some(*span), msg)); - } - if let Some((range, span)) = matching_created { - let msg = format!("this tag was also created here at offsets {}", HexRange(*range)); - helps.push((Some(*span), msg)); - } - if let Some((protecting_tag, protecting_tag_span, protection_span)) = protected { - helps.push((Some(*protecting_tag_span), format!("{:?} was protected due to a tag which was created here", protecting_tag))); - helps.push((Some(*protection_span), "this protector is live for this call".to_string())); - } - } None => {} } helps diff --git a/src/eval.rs b/src/eval.rs index fa252953fe..12f1f52c78 100644 --- a/src/eval.rs +++ b/src/eval.rs @@ -96,7 +96,7 @@ pub struct MiriConfig { /// The seed to use when non-determinism or randomness are required (e.g. ptr-to-int cast, `getrandom()`). pub seed: Option, /// The stacked borrows pointer ids to report about - pub tracked_pointer_tags: HashSet, + pub tracked_pointer_tags: HashSet, /// The stacked borrows call IDs to report about pub tracked_call_ids: HashSet, /// The allocation ids to report about. diff --git a/src/lib.rs b/src/lib.rs index 68489c9b47..1633667fca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,7 +89,7 @@ pub use crate::mono_hash_map::MonoHashMap; pub use crate::operator::EvalContextExt as OperatorEvalContextExt; pub use crate::range_map::RangeMap; pub use crate::stacked_borrows::{ - CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, PtrId, SbTag, SbTagExtra, + CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, SbTagExtra, Stack, Stacks, }; pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId}; diff --git a/src/machine.rs b/src/machine.rs index d6a65a2a44..5b18475458 100644 --- a/src/machine.rs +++ b/src/machine.rs @@ -140,8 +140,9 @@ pub enum Tag { #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(Pointer, 24); +// FIXME: this would with in 24bytes but layout optimizations are not smart enough // #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -// static_assert_size!(Pointer>, 24); +//static_assert_size!(Pointer>, 24); #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] static_assert_size!(ScalarMaybeUninit, 32); @@ -680,9 +681,10 @@ impl<'mir, 'tcx> Machine<'mir, 'tcx> for Evaluator<'mir, 'tcx> { } let absolute_addr = intptrcast::GlobalStateInner::rel_ptr_to_addr(ecx, ptr); let sb_tag = if let Some(stacked_borrows) = &ecx.machine.stacked_borrows { - stacked_borrows.borrow_mut().base_tag(ptr.provenance) + stacked_borrows.borrow_mut().base_ptr_tag(ptr.provenance) } else { - SbTag::Untagged + // Value does not matter, SB is disabled + SbTag::default() }; Pointer::new( Tag::Concrete { alloc_id: ptr.provenance, sb: sb_tag }, diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index 2340802762..e79116a28e 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -23,42 +23,29 @@ use crate::*; pub mod diagnostics; use diagnostics::{AllocHistory, TagHistory}; -pub type PtrId = NonZeroU64; pub type CallId = NonZeroU64; + // Even reading memory can have effects on the stack, so we need a `RefCell` here. pub type AllocExtra = RefCell; /// Tracking pointer provenance -#[derive(Copy, Clone, Hash, Eq)] -pub enum SbTag { - Tagged(PtrId), - Untagged, -} +#[derive(Copy, Clone, Hash, PartialEq, Eq)] +pub struct SbTag(NonZeroU64); impl SbTag { - fn as_u64(self) -> u64 { - match self { - SbTag::Tagged(id) => id.get(), - SbTag::Untagged => 0, - } + pub fn new(i: u64) -> Option { + NonZeroU64::new(i).map(SbTag) } -} -impl PartialEq for SbTag { - fn eq(&self, other: &Self) -> bool { - // The codegen for the derived Partialeq is bad here and includes a branch. - // Since this code is extremely hot, this is optimized here. - // https://github.com/rust-lang/rust/issues/49892 - self.as_u64() == other.as_u64() + // The default to be used when SB is disabled + pub fn default() -> Self { + Self::new(1).unwrap() } } impl fmt::Debug for SbTag { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - SbTag::Tagged(id) => write!(f, "<{}>", id), - SbTag::Untagged => write!(f, ""), - } + write!(f, "<{}>", self.0) } } @@ -73,7 +60,7 @@ pub enum SbTagExtra { impl fmt::Debug for SbTagExtra { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - SbTagExtra::Concrete(tag) => write!(f, "{tag:?}"), + SbTagExtra::Concrete(pid) => write!(f, "{pid:?}"), SbTagExtra::Wildcard => write!(f, ""), } } @@ -82,7 +69,7 @@ impl fmt::Debug for SbTagExtra { impl SbTagExtra { fn and_then(self, f: impl FnOnce(SbTag) -> Option) -> Option { match self { - SbTagExtra::Concrete(tag) => f(tag), + SbTagExtra::Concrete(pid) => f(pid), SbTagExtra::Wildcard => None, } } @@ -130,15 +117,15 @@ pub struct Stack { /// Used *mostly* as a stack; never empty. /// Invariants: /// * Above a `SharedReadOnly` there can only be more `SharedReadOnly`. - /// * Except for `Untagged`, no tag occurs in the stack more than once. + /// * No tag occurs in the stack more than once. borrows: Vec, /// If this is `Some(id)`, then the actual current stack is unknown. This can happen when /// wildcard pointers are used to access this location. What we do know is that `borrows` are at - /// the top of the stack, and below it are arbitrarily many items whose `tag` is either - /// `Untagged` or strictly less than `id`. + /// the top of the stack, and below it are arbitrarily many items whose `tag` is strictly less + /// than `id`. /// When the bottom is unknown, `borrows` always has a `SharedReadOnly` or `Unique` at the bottom; /// we never have the unknown-to-known boundary in an SRW group. - unknown_bottom: Option, + unknown_bottom: Option, } /// Extra per-allocation state. @@ -156,21 +143,19 @@ pub struct Stacks { #[derive(Debug)] pub struct GlobalStateInner { /// Next unused pointer ID (tag). - next_ptr_id: PtrId, + next_ptr_tag: SbTag, /// Table storing the "base" tag for each allocation. /// The base tag is the one used for the initial pointer. /// We need this in a separate table to handle cyclic statics. - base_ptr_ids: FxHashMap, + base_ptr_tags: FxHashMap, /// Next unused call ID (for protectors). next_call_id: CallId, /// Those call IDs corresponding to functions that are still running. active_calls: FxHashSet, /// The pointer ids to trace - tracked_pointer_tags: HashSet, + tracked_pointer_tags: HashSet, /// The call ids to trace tracked_call_ids: HashSet, - /// Whether to track raw pointers. - tag_raw: bool, } /// We need interior mutable access to the global state. @@ -219,24 +204,23 @@ impl fmt::Display for RefKind { /// Utilities for initialization and ID generation impl GlobalStateInner { - pub fn new(tracked_pointer_tags: HashSet, tracked_call_ids: HashSet) -> Self { + pub fn new(tracked_pointer_tags: HashSet, tracked_call_ids: HashSet) -> Self { GlobalStateInner { - next_ptr_id: NonZeroU64::new(1).unwrap(), - base_ptr_ids: FxHashMap::default(), + next_ptr_tag: SbTag(NonZeroU64::new(1).unwrap()), + base_ptr_tags: FxHashMap::default(), next_call_id: NonZeroU64::new(1).unwrap(), active_calls: FxHashSet::default(), tracked_pointer_tags, tracked_call_ids, - tag_raw: true, } } - fn new_ptr(&mut self) -> PtrId { - let id = self.next_ptr_id; + fn new_ptr(&mut self) -> SbTag { + let id = self.next_ptr_tag; if self.tracked_pointer_tags.contains(&id) { - register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(id)); + register_diagnostic(NonHaltingDiagnostic::CreatedPointerTag(id.0)); } - self.next_ptr_id = NonZeroU64::new(id.get() + 1).unwrap(); + self.next_ptr_tag = SbTag(NonZeroU64::new(id.0.get() + 1).unwrap()); id } @@ -259,22 +243,14 @@ impl GlobalStateInner { self.active_calls.contains(&id) } - pub fn base_tag(&mut self, id: AllocId) -> SbTag { - self.base_ptr_ids.get(&id).copied().unwrap_or_else(|| { - let tag = SbTag::Tagged(self.new_ptr()); + pub fn base_ptr_tag(&mut self, id: AllocId) -> SbTag { + self.base_ptr_tags.get(&id).copied().unwrap_or_else(|| { + let tag = self.new_ptr(); trace!("New allocation {:?} has base tag {:?}", id, tag); - self.base_ptr_ids.try_insert(id, tag).unwrap(); + self.base_ptr_tags.try_insert(id, tag).unwrap(); tag }) } - - pub fn base_tag_untagged(&mut self, id: AllocId) -> SbTag { - trace!("New allocation {:?} has no base tag (untagged)", id); - let tag = SbTag::Untagged; - // This must only be done on new allocations. - self.base_ptr_ids.try_insert(id, tag).unwrap(); - tag - } } /// Error reporting @@ -364,10 +340,7 @@ impl<'tcx> Stack { // Couldn't find it in the stack; but if there is an unknown bottom it might be there. let found = self.unknown_bottom.is_some_and(|&unknown_limit| { - match tag { - SbTag::Tagged(tag_id) => tag_id < unknown_limit, // unknown_limit is an upper bound for what can be in the unknown bottom. - SbTag::Untagged => true, // yeah whatever - } + tag.0 < unknown_limit.0 // unknown_limit is an upper bound for what can be in the unknown bottom. }); if found { Ok(None) } else { Err(()) } } @@ -408,23 +381,22 @@ impl<'tcx> Stack { /// Within `provoking_access, the `AllocRange` refers the entire operation, and /// the `Size` refers to the specific location in the `AllocRange` that we are /// currently checking. - fn check_protector( + fn item_popped( item: &Item, provoking_access: Option<(SbTagExtra, AllocRange, Size, AccessKind)>, // just for debug printing and error messages global: &GlobalStateInner, alloc_history: &mut AllocHistory, ) -> InterpResult<'tcx> { - if let SbTag::Tagged(id) = item.tag { - if global.tracked_pointer_tags.contains(&id) { - register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag( - *item, - provoking_access.map(|(tag, _alloc_range, _size, access)| (tag, access)), - )); - } + if global.tracked_pointer_tags.contains(&item.tag) { + register_diagnostic(NonHaltingDiagnostic::PoppedPointerTag( + *item, + provoking_access.map(|(tag, _alloc_range, _size, access)| (tag, access)), + )); } + if let Some(call) = item.protector { if global.is_active(call) { - if let Some((tag, alloc_range, offset, _access)) = provoking_access { + if let Some((tag, _alloc_range, _offset, _access)) = provoking_access { Err(err_sb_ub( format!( "not granting access to tag {:?} because incompatible item is protected: {:?}", @@ -434,8 +406,6 @@ impl<'tcx> Stack { tag.and_then(|tag| { alloc_history.get_logs_relevant_to( tag, - alloc_range, - offset, Some(item.tag), ) }), @@ -491,7 +461,7 @@ impl<'tcx> Stack { }; for item in self.borrows.drain(first_incompatible_idx..).rev() { trace!("access: popping item {:?}", item); - Stack::check_protector( + Stack::item_popped( &item, Some((tag, alloc_range, offset, access)), global, @@ -520,7 +490,7 @@ impl<'tcx> Stack { if item.perm == Permission::Unique { trace!("access: disabling item {:?}", item); - Stack::check_protector( + Stack::item_popped( item, Some((tag, alloc_range, offset, access)), global, @@ -540,21 +510,19 @@ impl<'tcx> Stack { for item in &self.borrows { // Skip disabled items, they cannot be matched anyway. if !matches!(item.perm, Permission::Disabled) { - if let SbTag::Tagged(tag) = item.tag { - // We are looking for a strict upper bound, so add 1 to this tag. - max = cmp::max(tag.checked_add(1).unwrap(), max); - } + // We are looking for a strict upper bound, so add 1 to this tag. + max = cmp::max(item.tag.0.checked_add(1).unwrap(), max); } } if let Some(unk) = self.unknown_bottom { - max = cmp::max(unk, max); + max = cmp::max(unk.0, max); } // Use `max` as new strict upper bound for everything. trace!( "access: forgetting stack to upper bound {max} due to wildcard or unknown access" ); self.borrows.clear(); - self.unknown_bottom = Some(max); + self.unknown_bottom = Some(SbTag(max)); } // Done. @@ -566,7 +534,7 @@ impl<'tcx> Stack { fn dealloc( &mut self, tag: SbTagExtra, - (alloc_id, alloc_range, offset): (AllocId, AllocRange, Size), // just for debug printing and error messages + (alloc_id, _alloc_range, _offset): (AllocId, AllocRange, Size), // just for debug printing and error messages global: &GlobalStateInner, alloc_history: &mut AllocHistory, exposed_tags: &FxHashSet, @@ -578,13 +546,13 @@ impl<'tcx> Stack { tag, alloc_id, ), None, - tag.and_then(|tag| alloc_history.get_logs_relevant_to(tag, alloc_range, offset, None)), + tag.and_then(|tag| alloc_history.get_logs_relevant_to(tag, None)), ) })?; // Step 2: Remove all items. Also checks for protectors. for item in self.borrows.drain(..).rev() { - Stack::check_protector(&item, None, global, alloc_history)?; + Stack::item_popped(&item, None, global, alloc_history)?; } Ok(()) } @@ -632,7 +600,7 @@ impl<'tcx> Stack { // (for all we know, it might join an SRW group inside the unknown). trace!("reborrow: forgetting stack entirely due to SharedReadWrite reborrow from wildcard or unknown"); self.borrows.clear(); - self.unknown_bottom = Some(global.next_ptr_id); + self.unknown_bottom = Some(global.next_ptr_tag); return Ok(()); }; @@ -726,30 +694,9 @@ impl Stacks { // not through a pointer). That is, whenever we directly write to a local, this will pop // everything else off the stack, invalidating all previous pointers, // and in particular, *all* raw pointers. - MemoryKind::Stack => (extra.base_tag(id), Permission::Unique), - // `Global` memory can be referenced by global pointers from `tcx`. - // Thus we call `global_base_ptr` such that the global pointers get the same tag - // as what we use here. - // `ExternStatic` is used for extern statics, so the same reasoning applies. - // The others are various forms of machine-managed special global memory, and we can get - // away with precise tracking there. - // The base pointer is not unique, so the base permission is `SharedReadWrite`. - MemoryKind::CallerLocation - | MemoryKind::Machine( - MiriMemoryKind::Global - | MiriMemoryKind::ExternStatic - | MiriMemoryKind::Tls - | MiriMemoryKind::Runtime - | MiriMemoryKind::Machine, - ) => (extra.base_tag(id), Permission::SharedReadWrite), - // Heap allocations we only track precisely when raw pointers are tagged, for now. - MemoryKind::Machine( - MiriMemoryKind::Rust | MiriMemoryKind::C | MiriMemoryKind::WinHeap, - ) => { - let tag = - if extra.tag_raw { extra.base_tag(id) } else { extra.base_tag_untagged(id) }; - (tag, Permission::SharedReadWrite) - } + MemoryKind::Stack => (extra.base_ptr_tag(id), Permission::Unique), + // Everything else is shared by default. + _ => (extra.base_ptr_tag(id), Permission::SharedReadWrite), }; let mut stacks = Stacks::new(size, perm, base_tag); stacks.history.log_creation( @@ -1039,15 +986,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }; // Compute new borrow. - let new_tag = { - let mem_extra = this.machine.stacked_borrows.as_mut().unwrap().get_mut(); - match kind { - // Give up tracking for raw pointers. - RefKind::Raw { .. } if !mem_extra.tag_raw => SbTag::Untagged, - // All other pointers are properly tracked. - _ => SbTag::Tagged(mem_extra.new_ptr()), - } - }; + let new_tag = this.machine.stacked_borrows.as_mut().unwrap().get_mut().new_ptr(); // Reborrow. let alloc_id = this.reborrow(&place, size, kind, new_tag, protect)?; diff --git a/src/stacked_borrows/diagnostics.rs b/src/stacked_borrows/diagnostics.rs index a4a7f5e7a1..0a7edcdc89 100644 --- a/src/stacked_borrows/diagnostics.rs +++ b/src/stacked_borrows/diagnostics.rs @@ -32,7 +32,6 @@ struct Protection { #[derive(Clone, Debug)] struct Event { - time: usize, parent: Option, tag: SbTag, range: AllocRange, @@ -46,12 +45,6 @@ pub enum TagHistory { invalidated: Option<(AllocRange, SpanData)>, protected: Option<(SbTag, SpanData, SpanData)>, }, - Untagged { - recently_created: Option<(AllocRange, SpanData)>, - recently_invalidated: Option<(AllocRange, SpanData)>, - matching_created: Option<(AllocRange, SpanData)>, - protected: Option<(SbTag, SpanData, SpanData)>, - }, } impl AllocHistory { @@ -72,7 +65,7 @@ impl AllocHistory { current_span: &mut CurrentSpan<'_, '_, '_>, ) { let span = current_span.get(); - self.creations.push(Event { parent, tag, range, span, time: self.current_time }); + self.creations.push(Event { parent, tag, range, span }); self.current_time += 1; } @@ -83,7 +76,7 @@ impl AllocHistory { current_span: &mut CurrentSpan<'_, '_, '_>, ) { let span = current_span.get(); - self.invalidations.push(Event { parent: None, tag, range, span, time: self.current_time }); + self.invalidations.push(Event { parent: None, tag, range, span }); self.current_time += 1; } @@ -101,8 +94,6 @@ impl AllocHistory { pub fn get_logs_relevant_to( &self, tag: SbTag, - alloc_range: AllocRange, - offset: Size, protector_tag: Option, ) -> Option { let protected = protector_tag @@ -125,74 +116,17 @@ impl AllocHistory { }) }); - if let SbTag::Tagged(_) = tag { - let get_matching = |events: &[Event]| { - events.iter().rev().find_map(|event| { - if event.tag == tag { Some((event.range, event.span.data())) } else { None } - }) - }; - Some(TagHistory::Tagged { - tag, - created: get_matching(&self.creations)?, - invalidated: get_matching(&self.invalidations), - protected, - }) - } else { - let mut created_time = 0; - // Find the most recently created tag that satsfies this offset - let recently_created = self.creations.iter().rev().find_map(|event| { - if event.tag == tag && offset >= event.range.start && offset < event.range.end() { - created_time = event.time; - Some((event.range, event.span.data())) - } else { - None - } - }); - - // Find a different recently created tag that satisfies this whole operation, predates - // the recently created tag, and has a different span. - // We're trying to make a guess at which span the user wanted to provide the tag that - // they're using. - let matching_created = recently_created.and_then(|(_created_range, created_span)| { - self.creations.iter().rev().find_map(|event| { - if event.tag == tag - && alloc_range.start >= event.range.start - && alloc_range.end() <= event.range.end() - && event.span.data() != created_span - && event.time != created_time - { - Some((event.range, event.span.data())) - } else { - None - } - }) - }); - - // Find the most recent invalidation of this tag which post-dates the creation - let recently_invalidated = recently_created.and_then(|_| { - self.invalidations - .iter() - .rev() - .take_while(|event| event.time > created_time) - .find_map(|event| { - if event.tag == tag - && offset >= event.range.start - && offset < event.range.end() - { - Some((event.range, event.span.data())) - } else { - None - } - }) - }); - - Some(TagHistory::Untagged { - recently_created, - matching_created, - recently_invalidated, - protected, + let get_matching = |events: &[Event]| { + events.iter().rev().find_map(|event| { + if event.tag == tag { Some((event.range, event.span.data())) } else { None } }) - } + }; + Some(TagHistory::Tagged { + tag, + created: get_matching(&self.creations)?, + invalidated: get_matching(&self.invalidations), + protected, + }) } /// Report a descriptive error when `new` could not be granted from `derived_from`. @@ -215,7 +149,7 @@ impl AllocHistory { format!("{}{}", action, error_cause(stack, derived_from)), Some(operation_summary("a reborrow", alloc_id, alloc_range)), derived_from.and_then(|derived_from| { - self.get_logs_relevant_to(derived_from, alloc_range, error_offset, None) + self.get_logs_relevant_to(derived_from, None) }), ) } @@ -238,7 +172,7 @@ impl AllocHistory { err_sb_ub( format!("{}{}", action, error_cause(stack, tag)), Some(operation_summary("an access", alloc_id, alloc_range)), - tag.and_then(|tag| self.get_logs_relevant_to(tag, alloc_range, error_offset, None)), + tag.and_then(|tag| self.get_logs_relevant_to(tag, None)), ) } } From 4120425108855824356019cc3e7f6c2bfff157c1 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 22:07:02 -0400 Subject: [PATCH 04/10] readme: move some things around --- README.md | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index efdbf5143d..d7c50e9613 100644 --- a/README.md +++ b/README.md @@ -289,6 +289,11 @@ environment variable. We first document the most relevant and most commonly used `-Zmiri-disable-isolation` is set. * `-Zmiri-ignore-leaks` disables the memory leak checker, and also allows some remaining threads to exist when the main thread exits. +* `-Zmiri-permissive-provenance` disables the warning for integer-to-pointer casts and + [`ptr::from_exposed_addr`](https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html). + This will necessarily miss some bugs as those operations are not efficiently and accurately + implementable in a sanitizer, but it will only miss bugs that concern memory/pointers which is + subject to these operations. * `-Zmiri-preemption-rate` configures the probability that at the end of a basic block, the active thread will be preempted. The default is `0.01` (i.e., 1%). Setting this to `0` disables preemption. @@ -307,6 +312,16 @@ environment variable. We first document the most relevant and most commonly used provenance](https://github.com/rust-lang/rust/issues/95228) checking in Miri. This means that casting an integer to a pointer yields a result with 'invalid' provenance, i.e., with provenance that cannot be used for any memory access. +* `-Zmiri-symbolic-alignment-check` makes the alignment check more strict. By default, alignment is + checked by casting the pointer to an integer, and making sure that is a multiple of the alignment. + This can lead to cases where a program passes the alignment check by pure chance, because things + "happened to be" sufficiently aligned -- there is no UB in this execution but there would be UB in + others. To avoid such cases, the symbolic alignment check only takes into account the requested + alignment of the relevant allocation, and the offset into that allocation. This avoids missing + such bugs, but it also incurs some false positives when the code does manual integer arithmetic to + ensure alignment. (The standard library `align_to` method works fine in both modes; under + symbolic alignment it only fills the middle slice when the allocation guarantees sufficient + alignment.) The remaining flags are for advanced use only, and more likely to change or be removed. Some of these are **unsound**, which means they can lead @@ -354,23 +369,6 @@ to Miri failing to detect cases of undefined behavior in a program. application instead of raising an error within the context of Miri (and halting execution). Note that code might not expect these operations to ever panic, so this flag can lead to strange (mis)behavior. -* `-Zmiri-permissive-provenance` disables the warning for integer-to-pointer casts and - [`ptr::from_exposed_addr`](https://doc.rust-lang.org/nightly/std/ptr/fn.from_exposed_addr.html). - This will necessarily miss some bugs as those operations are not efficiently and accurately - implementable in a sanitizer, but it will only miss bugs that concern memory/pointers which is - subject to these operations. -* `-Zmiri-symbolic-alignment-check` makes the alignment check more strict. By - default, alignment is checked by casting the pointer to an integer, and making - sure that is a multiple of the alignment. This can lead to cases where a - program passes the alignment check by pure chance, because things "happened to - be" sufficiently aligned -- there is no UB in this execution but there would - be UB in others. To avoid such cases, the symbolic alignment check only takes - into account the requested alignment of the relevant allocation, and the - offset into that allocation. This avoids missing such bugs, but it also - incurs some false positives when the code does manual integer arithmetic to - ensure alignment. (The standard library `align_to` method works fine in both - modes; under symbolic alignment it only fills the middle slice when the - allocation guarantees sufficient alignment.) * `-Zmiri-track-alloc-id=,,...` shows a backtrace when the given allocations are being allocated or freed. This helps in debugging memory leaks and use after free bugs. Specifying this argument multiple times does not overwrite the previous From 1a5dfbeb7a9c4289bb1e8903a8768603e673f128 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 22:27:38 -0400 Subject: [PATCH 05/10] fmt --- src/intptrcast.rs | 2 +- src/lib.rs | 4 ++-- src/stacked_borrows.rs | 7 +------ src/stacked_borrows/diagnostics.rs | 4 +--- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/src/intptrcast.rs b/src/intptrcast.rs index cb0d6517b9..83739c48ef 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -94,7 +94,7 @@ impl<'mir, 'tcx> GlobalStateInner { if global_state.exposed.contains(&alloc_id) { // FIXME: this catches `InterpError`, which we should not usually do. // We might need a proper fallible API from `memory.rs` to avoid this though. - if let Ok(_) = ecx.get_alloc_size_and_align(alloc_id, AllocCheck::Live) { + if ecx.get_alloc_size_and_align(alloc_id, AllocCheck::Live).is_ok() { return Some(alloc_id); } } diff --git a/src/lib.rs b/src/lib.rs index 1633667fca..621af171f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -89,8 +89,8 @@ pub use crate::mono_hash_map::MonoHashMap; pub use crate::operator::EvalContextExt as OperatorEvalContextExt; pub use crate::range_map::RangeMap; pub use crate::stacked_borrows::{ - CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, SbTagExtra, - Stack, Stacks, + CallId, EvalContextExt as StackedBorEvalContextExt, Item, Permission, SbTag, SbTagExtra, Stack, + Stacks, }; pub use crate::sync::{CondvarId, EvalContextExt as SyncEvalContextExt, MutexId, RwLockId}; pub use crate::thread::{ diff --git a/src/stacked_borrows.rs b/src/stacked_borrows.rs index e79116a28e..ea1132d3e1 100644 --- a/src/stacked_borrows.rs +++ b/src/stacked_borrows.rs @@ -403,12 +403,7 @@ impl<'tcx> Stack { tag, item ), None, - tag.and_then(|tag| { - alloc_history.get_logs_relevant_to( - tag, - Some(item.tag), - ) - }), + tag.and_then(|tag| alloc_history.get_logs_relevant_to(tag, Some(item.tag))), ))? } else { Err(err_sb_ub( diff --git a/src/stacked_borrows/diagnostics.rs b/src/stacked_borrows/diagnostics.rs index 0a7edcdc89..b1ff864bcd 100644 --- a/src/stacked_borrows/diagnostics.rs +++ b/src/stacked_borrows/diagnostics.rs @@ -148,9 +148,7 @@ impl AllocHistory { err_sb_ub( format!("{}{}", action, error_cause(stack, derived_from)), Some(operation_summary("a reborrow", alloc_id, alloc_range)), - derived_from.and_then(|derived_from| { - self.get_logs_relevant_to(derived_from, None) - }), + derived_from.and_then(|derived_from| self.get_logs_relevant_to(derived_from, None)), ) } From 3abec0e2afdc635b1e2f4cfaf971a7fcd9a9e332 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 23:00:54 -0400 Subject: [PATCH 06/10] make macOS happy --- test-cargo-miri/run-test.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test-cargo-miri/run-test.py b/test-cargo-miri/run-test.py index 42978c481b..a16019a05e 100755 --- a/test-cargo-miri/run-test.py +++ b/test-cargo-miri/run-test.py @@ -114,15 +114,16 @@ def test_cargo_miri_test(): default_ref = "test.cross-target.stdout.ref" if is_foreign else "test.default.stdout.ref" filter_ref = "test.filter.cross-target.stdout.ref" if is_foreign else "test.filter.stdout.ref" + # macOS needs permissive provenance inside getrandom. test("`cargo miri test`", cargo_miri("test"), default_ref, "test.stderr-empty.ref", - env={'MIRIFLAGS': "-Zmiri-seed=feed"}, + env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-seed=feed"}, ) test("`cargo miri test` (no isolation, no doctests)", cargo_miri("test") + ["--bins", "--tests"], # no `--lib`, we disabled that in `Cargo.toml` "test.cross-target.stdout.ref", "test.stderr-empty.ref", - env={'MIRIFLAGS': "-Zmiri-disable-isolation"}, + env={'MIRIFLAGS': "-Zmiri-permissive-provenance -Zmiri-disable-isolation"}, ) test("`cargo miri test` (with filter)", cargo_miri("test") + ["--", "--format=pretty", "le1"], @@ -131,6 +132,7 @@ def test_cargo_miri_test(): test("`cargo miri test` (test target)", cargo_miri("test") + ["--test", "test", "--", "--format=pretty"], "test.test-target.stdout.ref", "test.stderr-empty.ref", + env={'MIRIFLAGS': "-Zmiri-permissive-provenance"}, ) test("`cargo miri test` (bin target)", cargo_miri("test") + ["--bin", "cargo-miri-test", "--", "--format=pretty"], @@ -148,11 +150,13 @@ def test_cargo_miri_test(): test("`cargo miri test` (custom target dir)", cargo_miri("test") + ["--target-dir=custom-test"], default_ref, "test.stderr-empty.ref", + env={'MIRIFLAGS': "-Zmiri-permissive-provenance"}, ) del os.environ["CARGO_TARGET_DIR"] # this overrides `build.target-dir` passed by `--config`, so unset it test("`cargo miri test` (config-cli)", cargo_miri("test") + ["--config=build.target-dir=\"config-cli\"", "-Zunstable-options"], default_ref, "test.stderr-empty.ref", + env={'MIRIFLAGS': "-Zmiri-permissive-provenance"}, ) os.chdir(os.path.dirname(os.path.realpath(__file__))) From b479f092a86c5524c76088346ac53cd4d0f86e0a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 26 Jun 2022 23:14:16 -0400 Subject: [PATCH 07/10] avoid unnecessary indirection in miri-track-raw-pointers warning --- src/bin/miri.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bin/miri.rs b/src/bin/miri.rs index a56b4bc6d1..1ccc54d6be 100644 --- a/src/bin/miri.rs +++ b/src/bin/miri.rs @@ -385,7 +385,7 @@ fn main() { miri_config.mute_stdout_stderr = true; } else if arg == "-Zmiri-track-raw-pointers" { eprintln!( - "WARNING: -Zmiri-track-raw-pointers has been renamed to -Zmiri-tag-raw-pointers, the old name is deprecated." + "WARNING: `-Zmiri-track-raw-pointers` has no effect; it is enabled by default" ); } else if let Some(param) = arg.strip_prefix("-Zmiri-seed=") { if miri_config.seed.is_some() { From d9e7a3ae820b23d54ee9d1145e0295d1486601d6 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Jun 2022 08:35:25 -0400 Subject: [PATCH 08/10] typo Co-authored-by: Oli Scherer --- src/intptrcast.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/intptrcast.rs b/src/intptrcast.rs index 83739c48ef..5e6088303f 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -215,7 +215,7 @@ impl<'mir, 'tcx> GlobalStateInner { dl.overflowing_offset(base_addr, offset.bytes()).0 } - /// Whena pointer is used for a memory access, this computes where in which allocation the + /// When a pointer is used for a memory access, this computes where in which allocation the /// access is going. pub fn abs_ptr_to_rel( ecx: &MiriEvalContext<'mir, 'tcx>, From 67e89b53e24d6bdf56d5c063f2c8997ab7d2381f Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Jun 2022 20:04:46 -0400 Subject: [PATCH 09/10] fix warning text --- src/diagnostics.rs | 4 ++-- tests/pass/box.stderr | 4 ++-- tests/pass/extern_types.stderr | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 8176e51338..1a030bedd9 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -451,13 +451,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx format!("{op} was made to return an error due to isolation"), ProgressReport => format!("progress report: current operation being executed is here"), - Int2Ptr => format!("pointer-to-integer cast"), + Int2Ptr => format!("integer-to-pointer cast"), }; let (title, diag_level) = match e { RejectedIsolatedOp(_) => ("operation rejected by isolation", DiagLevel::Warning), - Int2Ptr => ("pointer-to-integer cast", DiagLevel::Warning), + Int2Ptr => ("integer-to-pointer cast", DiagLevel::Warning), CreatedPointerTag(..) | PoppedPointerTag(..) | CreatedCallId(..) diff --git a/tests/pass/box.stderr b/tests/pass/box.stderr index eac98bf2d1..eeb49eec5c 100644 --- a/tests/pass/box.stderr +++ b/tests/pass/box.stderr @@ -1,8 +1,8 @@ -warning: pointer-to-integer cast +warning: integer-to-pointer cast --> $DIR/box.rs:LL:CC | LL | let r2 = ((r as usize) + 0) as *mut i32; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, = help: which means that Miri might miss pointer bugs in this program diff --git a/tests/pass/extern_types.stderr b/tests/pass/extern_types.stderr index 730a430425..f23526b52b 100644 --- a/tests/pass/extern_types.stderr +++ b/tests/pass/extern_types.stderr @@ -1,8 +1,8 @@ -warning: pointer-to-integer cast +warning: integer-to-pointer cast --> $DIR/extern_types.rs:LL:CC | LL | let x: &Foo = unsafe { &*(16 as *const Foo) }; - | ^^^^^^^^^^^^^^^^^^ pointer-to-integer cast + | ^^^^^^^^^^^^^^^^^^ integer-to-pointer cast | = help: this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`, = help: which means that Miri might miss pointer bugs in this program From c1eddbc7fefe34bb0213261cb4aa18f4bc11b1c5 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Mon, 27 Jun 2022 20:22:50 -0400 Subject: [PATCH 10/10] show int2ptr warning once for each span (but don't duplicate the long help) --- src/diagnostics.rs | 10 ++++++---- src/intptrcast.rs | 17 ++++++++++++----- src/lib.rs | 1 + tests/pass/box.stderr | 13 +++++++++++++ 4 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/diagnostics.rs b/src/diagnostics.rs index 1a030bedd9..83949a75de 100644 --- a/src/diagnostics.rs +++ b/src/diagnostics.rs @@ -69,7 +69,9 @@ pub enum NonHaltingDiagnostic { FreedAlloc(AllocId), RejectedIsolatedOp(String), ProgressReport, - Int2Ptr, + Int2Ptr { + details: bool, + }, } /// Level of Miri specific diagnostics @@ -451,13 +453,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx format!("{op} was made to return an error due to isolation"), ProgressReport => format!("progress report: current operation being executed is here"), - Int2Ptr => format!("integer-to-pointer cast"), + Int2Ptr { .. } => format!("integer-to-pointer cast"), }; let (title, diag_level) = match e { RejectedIsolatedOp(_) => ("operation rejected by isolation", DiagLevel::Warning), - Int2Ptr => ("integer-to-pointer cast", DiagLevel::Warning), + Int2Ptr { .. } => ("integer-to-pointer cast", DiagLevel::Warning), CreatedPointerTag(..) | PoppedPointerTag(..) | CreatedCallId(..) @@ -467,7 +469,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx }; let helps = match e { - Int2Ptr => + Int2Ptr { details: true } => vec![ (None, format!("this program is using integer-to-pointer casts or (equivalently) `from_exposed_addr`,")), (None, format!("which means that Miri might miss pointer bugs in this program")), diff --git a/src/intptrcast.rs b/src/intptrcast.rs index 5e6088303f..a95b20868d 100644 --- a/src/intptrcast.rs +++ b/src/intptrcast.rs @@ -5,6 +5,7 @@ use log::trace; use rand::Rng; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; +use rustc_span::Span; use rustc_target::abi::{HasDataLayout, Size}; use crate::*; @@ -140,12 +141,18 @@ impl<'mir, 'tcx> GlobalStateInner { match global_state.provenance_mode { ProvenanceMode::Default => { - // The first time this happens, print a warning. - use std::sync::atomic::{AtomicBool, Ordering}; - static FIRST_WARNING: AtomicBool = AtomicBool::new(true); - if FIRST_WARNING.swap(false, Ordering::Relaxed) { - register_diagnostic(NonHaltingDiagnostic::Int2Ptr); + // The first time this happens at a particular location, print a warning. + thread_local! { + // `Span` is non-`Send`, so we use a thread-local instead. + static PAST_WARNINGS: RefCell> = RefCell::default(); } + PAST_WARNINGS.with_borrow_mut(|past_warnings| { + let first = past_warnings.is_empty(); + if past_warnings.insert(ecx.cur_span()) { + // Newly inserted, so first time we see this span. + register_diagnostic(NonHaltingDiagnostic::Int2Ptr { details: first }); + } + }); } ProvenanceMode::Strict => { throw_unsup_format!( diff --git a/src/lib.rs b/src/lib.rs index 621af171f4..e199fae31e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -8,6 +8,7 @@ #![feature(yeet_expr)] #![feature(is_some_with)] #![feature(nonzero_ops)] +#![feature(local_key_cell_methods)] #![warn(rust_2018_idioms)] #![allow( clippy::collapsible_else_if, diff --git a/tests/pass/box.stderr b/tests/pass/box.stderr index eeb49eec5c..d821fcd9d1 100644 --- a/tests/pass/box.stderr +++ b/tests/pass/box.stderr @@ -18,3 +18,16 @@ note: inside `main` at $DIR/box.rs:LL:CC LL | into_raw(); | ^^^^^^^^^^ +warning: integer-to-pointer cast + --> $DIR/box.rs:LL:CC + | +LL | let r = ((u.as_ptr() as usize) + 0) as *mut i32; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ integer-to-pointer cast + | + = note: inside `into_unique` at $DIR/box.rs:LL:CC +note: inside `main` at $DIR/box.rs:LL:CC + --> $DIR/box.rs:LL:CC + | +LL | into_unique(); + | ^^^^^^^^^^^^^ +