diff options
| author | bors <bors@rust-lang.org> | 2022-12-22 17:48:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-12-22 17:48:43 +0000 |
| commit | cca80b9a81d495f543cdc122fa330c7f68fff3a8 (patch) | |
| tree | fd3758d2b90812aa48579864bd465db68ded874c /src | |
| parent | e5e4eef02d443eae5089a330e59a69a4f350db81 (diff) | |
| parent | 0229281d03d92eec1b167377fec1e9978af1f704 (diff) | |
| download | rust-cca80b9a81d495f543cdc122fa330c7f68fff3a8.tar.gz rust-cca80b9a81d495f543cdc122fa330c7f68fff3a8.zip | |
Auto merge of #103957 - JakobDegen:drop-retag, r=RalfJung
Retag as FnEntry on `drop_in_place` This commit changes the mir drop shim to always retag its argument as if it were a `&mut`. cc rust-lang/unsafe-code-guidelines#373
Diffstat (limited to 'src')
7 files changed, 151 insertions, 2 deletions
diff --git a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir index 14f297e948b..f495f147be3 100644 --- a/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir +++ b/src/test/mir-opt/retag.core.ptr-drop_in_place.Test.SimplifyCfg-make_shim.after.mir @@ -3,11 +3,14 @@ fn std::ptr::drop_in_place(_1: *mut Test) -> () { let mut _0: (); // return place in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 let mut _2: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - let mut _3: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _3: &mut Test; // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + let mut _4: (); // in scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 bb0: { _2 = &mut (*_1); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 - _3 = <Test as Drop>::drop(move _2) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + Retag([fn entry] _2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _3 = &mut (*_2); // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 + _4 = <Test as Drop>::drop(move _3) -> bb1; // scope 0 at $SRC_DIR/core/src/ptr/mod.rs:+0:1: +0:56 // mir::Constant // + span: $SRC_DIR/core/src/ptr/mod.rs:LL:COL // + literal: Const { ty: for<'a> fn(&'a mut Test) {<Test as Drop>::drop}, val: Value(<ZST>) } diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.rs b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.rs new file mode 100644 index 00000000000..8cf63ee700b --- /dev/null +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.rs @@ -0,0 +1,27 @@ +//! Test that drop_in_place retags the entire place, +//! invalidating all aliases to it. + +// A zero-sized drop type -- the retagging of `fn drop` itself won't +// do anything (since it is zero-sized); we are entirely relying on the retagging +// in `drop_in_place` here. +#[repr(transparent)] +struct HasDrop; +impl Drop for HasDrop { + fn drop(&mut self) { + unsafe { + let _val = *P; + //~^ ERROR: /not granting access .* because that would remove .* which is strongly protected/ + } + } +} + +static mut P: *mut u8 = core::ptr::null_mut(); + +fn main() { + unsafe { + let mut x = (HasDrop, 0u8); + let x = core::ptr::addr_of_mut!(x); + P = x.cast(); + core::ptr::drop_in_place(x); + } +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr new file mode 100644 index 00000000000..bd51a6645a6 --- /dev/null +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_protector.stderr @@ -0,0 +1,33 @@ +error: Undefined Behavior: not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of call ID + --> $DIR/drop_in_place_protector.rs:LL:CC + | +LL | let _val = *P; + | ^^ not granting access to tag <TAG> because that would remove [Unique for <TAG>] which is strongly protected because it is an argument of 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 created by a SharedReadWrite retag at offsets [0x0..0x1] + --> $DIR/drop_in_place_protector.rs:LL:CC + | +LL | let x = core::ptr::addr_of_mut!(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ +help: <TAG> is this argument + --> $DIR/drop_in_place_protector.rs:LL:CC + | +LL | core::ptr::drop_in_place(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: BACKTRACE: + = note: inside `<HasDrop as std::ops::Drop>::drop` at $DIR/drop_in_place_protector.rs:LL:CC + = note: inside `std::ptr::drop_in_place::<HasDrop> - shim(Some(HasDrop))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC + = note: inside `std::ptr::drop_in_place::<(HasDrop, u8)> - shim(Some((HasDrop, u8)))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC +note: inside `main` + --> $DIR/drop_in_place_protector.rs:LL:CC + | +LL | core::ptr::drop_in_place(x); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `core::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs new file mode 100644 index 00000000000..8180e2f03a7 --- /dev/null +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.rs @@ -0,0 +1,12 @@ +//! Test that drop_in_place mutably retags the entire place, even for a type that does not need +//! dropping, ensuring among other things that it is writeable + +//@error-pattern: /retag .* for Unique permission .* only grants SharedReadOnly permission/ + +fn main() { + unsafe { + let x = 0u8; + let x = core::ptr::addr_of!(x); + core::ptr::drop_in_place(x.cast_mut()); + } +} diff --git a/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr new file mode 100644 index 00000000000..3f9e6708bda --- /dev/null +++ b/src/tools/miri/tests/fail/stacked_borrows/drop_in_place_retag.stderr @@ -0,0 +1,29 @@ +error: Undefined Behavior: trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location + --> RUSTLIB/core/src/ptr/mod.rs:LL:CC + | +LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | trying to retag from <TAG> for Unique permission at ALLOC[0x0], but that tag only grants SharedReadOnly permission for this location + | this error occurs as part of retag 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 created by a SharedReadOnly retag at offsets [0x0..0x1] + --> $DIR/drop_in_place_retag.rs:LL:CC + | +LL | let x = core::ptr::addr_of!(x); + | ^^^^^^^^^^^^^^^^^^^^^^ + = note: BACKTRACE: + = note: inside `std::ptr::drop_in_place::<u8> - shim(None)` at RUSTLIB/core/src/ptr/mod.rs:LL:CC +note: inside `main` + --> $DIR/drop_in_place_retag.rs:LL:CC + | +LL | core::ptr::drop_in_place(x.cast_mut()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the macro `core::ptr::addr_of` (in Nightly builds, run with -Z macro-backtrace for more info) + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs new file mode 100644 index 00000000000..cf3a558bb99 --- /dev/null +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.rs @@ -0,0 +1,25 @@ +#[repr(transparent)] +struct HasDrop(u8); + +impl Drop for HasDrop { + fn drop(&mut self) {} +} + +#[repr(C, align(2))] +struct PartialDrop { + a: HasDrop, + b: u8, +} + +//@error-pattern: /alignment 2 is required/ +fn main() { + unsafe { + // Create an unaligned pointer + let mut x = [0_u16; 2]; + let p = core::ptr::addr_of_mut!(x).cast::<u8>(); + let p = p.add(1); + let p = p.cast::<PartialDrop>(); + + core::ptr::drop_in_place(p); + } +} diff --git a/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr new file mode 100644 index 00000000000..ef20b43c118 --- /dev/null +++ b/src/tools/miri/tests/fail/unaligned_pointers/drop_in_place.stderr @@ -0,0 +1,20 @@ +error: Undefined Behavior: accessing memory with alignment ALIGN, but alignment ALIGN is required + --> RUSTLIB/core/src/ptr/mod.rs:LL:CC + | +LL | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ accessing memory with alignment ALIGN, but alignment ALIGN is required + | + = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior + = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information + = note: BACKTRACE: + = note: inside `std::ptr::drop_in_place::<PartialDrop> - shim(Some(PartialDrop))` at RUSTLIB/core/src/ptr/mod.rs:LL:CC +note: inside `main` + --> $DIR/drop_in_place.rs:LL:CC + | +LL | core::ptr::drop_in_place(p); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace + +error: aborting due to previous error + |
