From 8e449e88239536f029dbeb22ecf4e8281ebb4da4 Mon Sep 17 00:00:00 2001 From: wackbyte Date: Wed, 31 Jan 2024 02:52:19 -0500 Subject: [PATCH] fix: don't perform invalid reference cast (#554) Replaces it with a raw pointer. Avoids possible Undefined Behavior. Stripped-down example of how the current code fails in Miri: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=4b7ad1c81275f9213a60443a7edafc4f) Equivalent using the implementation from this PR: [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8e64a9b45aa78b8823f5453b9c54d3a5) --- crates/mun_runtime/src/lib.rs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/crates/mun_runtime/src/lib.rs b/crates/mun_runtime/src/lib.rs index 5619ea50..98b4ea95 100644 --- a/crates/mun_runtime/src/lib.rs +++ b/crates/mun_runtime/src/lib.rs @@ -669,10 +669,6 @@ impl<'name, T: InvokeArgs> InvokeErr<'name, T> { Output: 'o + ReturnTypeReflection + Marshal<'o>, 'r: 'o, { - // Safety: The output of `retry_impl` is guaranteed to only contain a shared - // reference. - let runtime = &*runtime; - loop { self = match unsafe { self.retry_impl(runtime) } { Ok(output) => return output, @@ -687,15 +683,14 @@ impl<'name, T: InvokeArgs> InvokeErr<'name, T> { /// /// # Safety /// - /// When calling this function, you have to guarantee that `runtime` is mutably - /// borrowed. The `Output` value can only contain a shared borrow of `runtime`. - unsafe fn retry_impl<'r, 'o, Output>(self, runtime: &'r Runtime) -> Result + /// When calling this function, you have to guarantee that `runtime` can be dereferenced and is + /// valid for `'o`. The `Output` value can only contain a shared borrow of `runtime`. + unsafe fn retry_impl<'o, Output>(self, runtime: *mut Runtime) -> Result where Output: 'o + ReturnTypeReflection + Marshal<'o>, - 'r: 'o, { - #[allow(invalid_reference_casting, invalid_reference_casting)] - let runtime = &mut *(runtime as *const Runtime as *mut Runtime); + // Safety: Guaranteed by the caller to be valid to dereference. + let runtime = &mut *runtime; eprintln!("{}", self.msg); while !runtime.update() {