From a2f107f5aeaa8224eadf220f4cf6c6ea666ba992 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 21 May 2022 08:39:45 +0200 Subject: [PATCH 1/3] use transmute for ptr::invalid --- src/lib.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ff4f40e..a66d918 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -361,6 +361,8 @@ //! [Strict Provenance]: https://github.com/rust-lang/rust/issues/95228 //! [Stacked Borrows]: https://plv.mpi-sws.org/rustbelt/stacked-borrows/ +use core::mem; + /// Creates an invalid pointer with the given address. /// /// This is *currently* equivalent to `addr as *const T` but it expresses the intended semantic @@ -383,7 +385,11 @@ #[must_use] pub const fn invalid(addr: usize) -> *const T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. - addr as *const T + // We use transmute rather than a cast so tools like Miri can tell that this + // is *not* the same as from_exposed_addr. + // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that + // pointer). + unsafe { mem::transmute(addr) } } /// Creates an invalid mutable pointer with the given address. @@ -408,7 +414,11 @@ pub const fn invalid(addr: usize) -> *const T { #[must_use] pub const fn invalid_mut(addr: usize) -> *mut T { // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic. - addr as *mut T + // We use transmute rather than a cast so tools like Miri can tell that this + // is *not* the same as from_exposed_addr. + // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that + // pointer). + unsafe { mem::transmute(addr) } } /// Convert an address back to a pointer, picking up a previously 'exposed' provenance. From 4cabc22cf28095e451fc31e88cded5bed6ac4f0b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 21 May 2022 08:47:28 +0200 Subject: [PATCH 2/3] only do the transmuting in Miri Miri only works on nightly so we will have the feature there --- src/lib.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index a66d918..d7429c4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -361,8 +361,6 @@ //! [Strict Provenance]: https://github.com/rust-lang/rust/issues/95228 //! [Stacked Borrows]: https://plv.mpi-sws.org/rustbelt/stacked-borrows/ -use core::mem; - /// Creates an invalid pointer with the given address. /// /// This is *currently* equivalent to `addr as *const T` but it expresses the intended semantic @@ -389,7 +387,11 @@ pub const fn invalid(addr: usize) -> *const T { // is *not* the same as from_exposed_addr. // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that // pointer). - unsafe { mem::transmute(addr) } + #[cfg(miri)] + return unsafe { core::mem::transmute(addr) }; + // Outside Miri we keep using casts, so that we can be a `const fn` on old Rust (pre-1.56). + #[cfg(not(miri))] + return addr as *const T; } /// Creates an invalid mutable pointer with the given address. @@ -418,7 +420,11 @@ pub const fn invalid_mut(addr: usize) -> *mut T { // is *not* the same as from_exposed_addr. // SAFETY: every valid integer is also a valid pointer (as long as you don't dereference that // pointer). - unsafe { mem::transmute(addr) } + #[cfg(miri)] + return unsafe { core::mem::transmute(addr) }; + // Outside Miri we keep using casts, so that we can be a `const fn` on old Rust (pre-1.56). + #[cfg(not(miri))] + return addr as *mut T; } /// Convert an address back to a pointer, picking up a previously 'exposed' provenance. From 88632b514d27aad16284e48edc5392bbef19ea1b Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 21 May 2022 08:49:21 +0200 Subject: [PATCH 3/3] ensure it actually builds and works in Miri --- .github/workflows/rust.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 74676ff..f1b2a9c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -32,3 +32,15 @@ jobs: run: cargo build --verbose - name: Run tests run: cargo test --verbose + + miri: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install Miri + run: | + rustup toolchain install nightly --component miri + rustup override set nightly + cargo miri setup + - name: Test with Miri + run: cargo miri test