Skip to content

Commit 4feb866

Browse files
authored
Rollup merge of #138352 - RalfJung:miri-native-calls-exposed, r=oli-obk
miri native_calls: ensure we actually expose *mutable* provenance to the memory FFI can access In native call mode, the interpreter memory itself is accessed directly by external code via pointers created from integers and passed via libffi, so we have to ensure the provenance in Miri itself (on the meta level) is sufficiently exposed. So far we only exposed the provenance for read-only accesses. This may we enough as that may actually be the same provenance as for mutable accesses, but it's hard to be sure, and anyway there's no reason to do such a gambit -- we have this function, `prepare_for_native_call`, which iterates all memory the call can access. let's just also (re-)expose Miri's own allocations there. We expose the read-only provenance for all of them and the mutable provenance for the mutable allocations. r? ``@oli-obk``
2 parents 954b88e + 3846f94 commit 4feb866

File tree

4 files changed

+12
-3
lines changed

4 files changed

+12
-3
lines changed

compiler/rustc_const_eval/src/interpret/memory.rs

+4
Original file line numberDiff line numberDiff line change
@@ -982,6 +982,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
982982
todo.push(id);
983983
}
984984
}
985+
// Also expose the provenance of the interpreter-level allocation, so it can
986+
// be read by FFI. The `black_box` is defensive programming as LLVM likes
987+
// to (incorrectly) optimize away ptr2int casts whose result is unused.
988+
std::hint::black_box(alloc.get_bytes_unchecked_raw().expose_provenance());
985989

986990
// Prepare for possible write from native code if mutable.
987991
if info.mutbl.is_mut() {

compiler/rustc_middle/src/mir/interpret/allocation.rs

+5
Original file line numberDiff line numberDiff line change
@@ -679,6 +679,11 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
679679
// Set provenance of all bytes to wildcard.
680680
self.provenance.write_wildcards(self.len());
681681

682+
// Also expose the provenance of the interpreter-level allocation, so it can
683+
// be written by FFI. The `black_box` is defensive programming as LLVM likes
684+
// to (incorrectly) optimize away ptr2int casts whose result is unused.
685+
std::hint::black_box(self.get_bytes_unchecked_raw_mut().expose_provenance());
686+
682687
Ok(())
683688
}
684689

src/tools/miri/src/alloc_addresses/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
198198
}
199199
AllocKind::Dead => unreachable!(),
200200
};
201-
// Ensure this pointer's provenance is exposed, so that it can be used by FFI code.
202-
return interp_ok(base_ptr.expose_provenance().try_into().unwrap());
201+
// We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
202+
return interp_ok(base_ptr.addr().try_into().unwrap());
203203
}
204204
// We are not in native lib mode, so we control the addresses ourselves.
205205
if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(

src/tools/miri/src/shims/native_lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ fn imm_to_carg<'tcx>(v: &ImmTy<'tcx>, cx: &impl HasDataLayout) -> InterpResult<'
266266
CArg::USize(v.to_scalar().to_target_usize(cx)?.try_into().unwrap()),
267267
ty::RawPtr(..) => {
268268
let s = v.to_scalar().to_pointer(cx)?.addr();
269-
// This relies on the `expose_provenance` in `addr_from_alloc_id`.
269+
// This relies on the `expose_provenance` in `prepare_for_native_call`.
270270
CArg::RawPtr(std::ptr::with_exposed_provenance_mut(s.bytes_usize()))
271271
}
272272
_ => throw_unsup_format!("unsupported argument type for native call: {}", v.layout.ty),

0 commit comments

Comments
 (0)