From 3846f942300c4fd8f43a8a8a1324ad5e358b9459 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Tue, 11 Mar 2025 14:32:03 +0100 Subject: [PATCH] miri native_calls: ensure we actually expose *mutable* provenance to the memory FFI can access --- compiler/rustc_const_eval/src/interpret/memory.rs | 4 ++++ compiler/rustc_middle/src/mir/interpret/allocation.rs | 5 +++++ src/tools/miri/src/alloc_addresses/mod.rs | 4 ++-- src/tools/miri/src/shims/native_lib.rs | 2 +- 4 files changed, 12 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs index ce0b5a350e030..e5af067362919 100644 --- a/compiler/rustc_const_eval/src/interpret/memory.rs +++ b/compiler/rustc_const_eval/src/interpret/memory.rs @@ -982,6 +982,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { todo.push(id); } } + // Also expose the provenance of the interpreter-level allocation, so it can + // be read by FFI. The `black_box` is defensive programming as LLVM likes + // to (incorrectly) optimize away ptr2int casts whose result is unused. + std::hint::black_box(alloc.get_bytes_unchecked_raw().expose_provenance()); // Prepare for possible write from native code if mutable. if info.mutbl.is_mut() { diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs index ba65a7118155c..b24f6bc7770dc 100644 --- a/compiler/rustc_middle/src/mir/interpret/allocation.rs +++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs @@ -679,6 +679,11 @@ impl Allocation // Set provenance of all bytes to wildcard. self.provenance.write_wildcards(self.len()); + // Also expose the provenance of the interpreter-level allocation, so it can + // be written by FFI. The `black_box` is defensive programming as LLVM likes + // to (incorrectly) optimize away ptr2int casts whose result is unused. + std::hint::black_box(self.get_bytes_unchecked_raw_mut().expose_provenance()); + Ok(()) } diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs index ff3a25e94bd5d..5d257029a46e5 100644 --- a/src/tools/miri/src/alloc_addresses/mod.rs +++ b/src/tools/miri/src/alloc_addresses/mod.rs @@ -198,8 +198,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> { } AllocKind::Dead => unreachable!(), }; - // Ensure this pointer's provenance is exposed, so that it can be used by FFI code. - return interp_ok(base_ptr.expose_provenance().try_into().unwrap()); + // We don't have to expose this pointer yet, we do that in `prepare_for_native_call`. + return interp_ok(base_ptr.addr().try_into().unwrap()); } // We are not in native lib mode, so we control the addresses ourselves. if let Some((reuse_addr, clock)) = global_state.reuse.take_addr( diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs index c6fcb0355eb80..0258a76c3e703 100644 --- a/src/tools/miri/src/shims/native_lib.rs +++ b/src/tools/miri/src/shims/native_lib.rs @@ -266,7 +266,7 @@ fn imm_to_carg<'tcx>(v: &ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<' CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()), ty::RawPtr(..) => { let s = v.to_scalar().to_pointer(cx)?.addr(); - // This relies on the `expose_provenance` in `addr_from_alloc_id`. + // This relies on the `expose_provenance` in `prepare_for_native_call`. CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize())) } _ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty),