about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJohannes Hostert <jhostert@ethz.ch>2025-09-11 17:00:59 +0200
committerJohannes Hostert <jhostert@ethz.ch>2025-09-11 17:18:20 +0200
commit2b5b191965571142cff8fab04aad9f243041ca19 (patch)
treecbd75c67840956b6e76ed83ab573dc7b48b317a6
parent906bfe94ed2cf99f388a1231258a3252e98f4741 (diff)
downloadrust-2b5b191965571142cff8fab04aad9f243041ca19.tar.gz
rust-2b5b191965571142cff8fab04aad9f243041ca19.zip
Fix miri issue 4579 by checking if the strong protector is actually "active".
Where "active" means that the accessed bit is set.

This also reverts miri PR 3831.
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs2
-rw-r--r--src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr15
-rw-r--r--src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr32
-rw-r--r--src/tools/miri/tests/pass/both_borrows/zero-sized-protected.rs (renamed from src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs)7
4 files changed, 4 insertions, 52 deletions
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index 1f29bcfc2b0..22bd63bd6b6 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -756,6 +756,8 @@ impl<'tcx> Tree {
                             // Don't check for protector if it is a Cell (see `unsafe_cell_deallocate` in `interior_mutability.rs`).
                             // Related to https://github.com/rust-lang/rust/issues/55005.
                             && !perm.permission().is_cell()
+                            // Only trigger UB if the accessed bit is set, i.e. if the protector is actually protecting this offset. See #4579.
+                            && perm.is_accessed()
                         {
                             Err(TransitionError::ProtectedDealloc)
                         } else {
diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr
deleted file mode 100644
index 3e4a7ccac36..00000000000
--- a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.stack.stderr
+++ /dev/null
@@ -1,15 +0,0 @@
-error: Undefined Behavior: entering unreachable code
-  --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-   |
-LL |     unsafe { std::hint::unreachable_unchecked() };
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
-   |
-   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
-   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
-   = note: BACKTRACE:
-   = note: inside `main` at tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to 1 previous error
-
diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr
deleted file mode 100644
index 66a7d7794e9..00000000000
--- a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.tree.stderr
+++ /dev/null
@@ -1,32 +0,0 @@
-error: Undefined Behavior: deallocation through <TAG> (root of the allocation) at ALLOC[0x0] is forbidden
-  --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-   |
-LL |     unsafe { dealloc(ptr, l) };
-   |              ^^^^^^^^^^^^^^^ Undefined Behavior occurred here
-   |
-   = 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: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/tree-borrows.md for further information
-   = help: the allocation of the accessed tag <TAG> (root of the allocation) also contains the strongly protected tag <TAG>
-   = help: the strongly protected tag <TAG> disallows deallocations
-help: the accessed tag <TAG> was created here
-  --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-   |
-LL |     let ptr = unsafe { alloc(l) };
-   |                        ^^^^^^^^
-help: the strongly protected tag <TAG> was created here, in the initial state Reserved
-  --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-   |
-LL | fn test(_x: &mut (), ptr: *mut u8, l: Layout) {
-   |         ^^
-   = note: BACKTRACE (of the first span):
-   = note: inside `test` at tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-note: inside `main`
-  --> tests/fail/both_borrows/zero-sized-protected.rs:LL:CC
-   |
-LL |     unsafe { test(&mut *ptr.cast::<()>(), ptr, l) };
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to 1 previous error
-
diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs b/src/tools/miri/tests/pass/both_borrows/zero-sized-protected.rs
index df9a73a444e..23d283ff4a1 100644
--- a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs
+++ b/src/tools/miri/tests/pass/both_borrows/zero-sized-protected.rs
@@ -3,16 +3,13 @@
 use std::alloc::{Layout, alloc, dealloc};
 
 // `x` is strongly protected but covers zero bytes.
-// Let's see if deallocating the allocation x points to is UB:
-// in TB, it is UB, but in SB it is not.
+// This should never be UB.
 fn test(_x: &mut (), ptr: *mut u8, l: Layout) {
-    unsafe { dealloc(ptr, l) }; //~[tree] ERROR: /deallocation .* is forbidden/
+    unsafe { dealloc(ptr, l) };
 }
 
 fn main() {
     let l = Layout::from_size_align(1, 1).unwrap();
     let ptr = unsafe { alloc(l) };
     unsafe { test(&mut *ptr.cast::<()>(), ptr, l) };
-    // In SB the test would pass if it weren't for this line.
-    unsafe { std::hint::unreachable_unchecked() }; //~[stack] ERROR: unreachable
 }