diff options
| author | Johannes Hostert <jhostert@ethz.ch> | 2024-07-04 10:59:30 +0200 |
|---|---|---|
| committer | Johannes Hostert <jhostert@ethz.ch> | 2024-07-04 12:05:33 +0200 |
| commit | 0a86e7966442e12fa2080727d08047fdd2d3e619 (patch) | |
| tree | 65e281d6b4c29d4d9a85525b6f43967c08e2c638 | |
| parent | 8ef2c6c6afd8f5b4d5c69278cc3dd986e37c574d (diff) | |
| download | rust-0a86e7966442e12fa2080727d08047fdd2d3e619.tar.gz rust-0a86e7966442e12fa2080727d08047fdd2d3e619.zip | |
Add UI test for protector end write semantics
| -rw-r--r-- | src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs | 35 | ||||
| -rw-r--r-- | src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr | 27 |
2 files changed, 62 insertions, 0 deletions
diff --git a/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs new file mode 100644 index 00000000000..238f6dba9d3 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.rs @@ -0,0 +1,35 @@ +//@compile-flags: -Zmiri-tree-borrows +// This test tests that TB's protector end semantics correctly ensure +// that protected activated writes can be reordered. +fn the_other_function(ref_to_fst_elem: &mut i32, ptr_to_vec: *mut i32) -> *mut i32 { + // Activate the reference. Afterwards, we should be able to reorder arbitrary writes. + *ref_to_fst_elem = 0; + // Here is such an arbitrary write. + // It could be moved down after the retag, in which case the `funky_ref` would be invalidated. + // We need to ensure that the `funky_ptr` is unusable even if the write to `ref_to_fst_elem` + // happens before the retag. + *ref_to_fst_elem = 42; + // this creates a reference that is Reserved Lazy on the first element (offset 0). + // It does so by doing a proper retag on the second element (offset 1), which is fine + // since nothing else happens at that offset, but the lazy init mechanism means it's + // also reserved at offset 0, but not initialized. + let funky_ptr_lazy_on_fst_elem = + unsafe { (&mut *(ptr_to_vec.wrapping_add(1))) as *mut i32 }.wrapping_sub(1); + // If we write to `ref_to_fst_elem` here, then any further access to `funky_ptr_lazy_on_fst_elem` would + // definitely be UB. Since the compiler ought to be able to reorder the write of `42` above down to + // here, that means we want this program to also be UB. + return funky_ptr_lazy_on_fst_elem; +} + +fn main() { + let mut v = vec![0, 1]; + // get a pointer to the root of the allocation + // note that it's not important it's the actual root, what matters is that it's a parent + // of both references that will be created + let ptr_to_vec = v.as_mut_ptr(); + let ref_to_fst_elem = unsafe { &mut *ptr_to_vec }; + let funky_ptr_lazy_on_fst_elem = the_other_function(ref_to_fst_elem, ptr_to_vec); + // now we try to use the funky lazy pointer. + // It should be UB, since the write-on-protector-end should disable it. + unsafe { println!("Value of funky: {}", *funky_ptr_lazy_on_fst_elem) } //~ ERROR: /reborrow through .* is forbidden/ +} diff --git a/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr new file mode 100644 index 00000000000..955abd144c7 --- /dev/null +++ b/src/tools/miri/tests/fail/tree_borrows/protector-write-lazy.stderr @@ -0,0 +1,27 @@ +error: Undefined Behavior: reborrow through <TAG> at ALLOC[0x0] is forbidden + --> $DIR/protector-write-lazy.rs:LL:CC + | +LL | unsafe { println!("Value of funky: {}", *funky_ptr_lazy_on_fst_elem) } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ reborrow through <TAG> at ALLOC[0x0] is forbidden + | + = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental + = help: the accessed tag <TAG> has state Disabled which forbids this reborrow (acting as a child read access) +help: the accessed tag <TAG> was created here, in the initial state Reserved + --> $DIR/protector-write-lazy.rs:LL:CC + | +LL | unsafe { (&mut *(ptr_to_vec.wrapping_add(1))) as *mut i32 }.wrapping_sub(1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: the accessed tag <TAG> later transitioned to Disabled due to a protector release (acting as a foreign write access) on every location previously accessed by this tag + --> $DIR/protector-write-lazy.rs:LL:CC + | +LL | } + | ^ + = help: this transition corresponds to a loss of read and write permissions + = note: BACKTRACE (of the first span): + = note: inside `main` at $DIR/protector-write-lazy.rs:LL:CC + = note: this error originates in the macro `$crate::format_args_nl` which comes from the expansion of the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to 1 previous error + |
