Auto merge of #1052 - RalfJung:icefix, r=RalfJung

fix ICE due to dangling pointers in Stacked Borrows

Fixes https://github.com/rust-lang/miri/issues/1050. Thanks to @CAD97 for the report!
This commit is contained in:
bors 2019-11-14 09:27:03 +00:00
commit bf96b47d13
4 changed files with 17 additions and 4 deletions

View file

@ -533,9 +533,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
) -> InterpResult<'tcx> {
let this = self.eval_context_mut();
let protector = if protect { Some(this.frame().extra) } else { None };
let ptr = this.memory.check_ptr_access(place.ptr, size, place.align)
.expect("validity checks should have excluded dangling/unaligned pointer")
.expect("we shouldn't get here for ZST");
let ptr = place.ptr.to_ptr().expect("we should have a proper pointer");
trace!("reborrow: {} reference {:?} derived from {:?} (pointee {}): {:?}, size {}",
kind, new_tag, ptr.tag, place.layout.ty, ptr.erase_tag(), size.bytes());
@ -583,11 +581,13 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
let size = this.size_and_align_of_mplace(place)?
.map(|(size, _)| size)
.unwrap_or_else(|| place.layout.size);
// We can see dangling ptrs in here e.g. after a Box's `Unique` was
// updated using "self.0 = ..." (can happen in Box::from_raw); see miri#1050.
let place = this.mplace_access_checked(place)?;
if size == Size::ZERO {
// Nothing to do for ZSTs.
return Ok(*val);
}
let place = this.force_mplace_ptr(place)?;
// Compute new borrow.
let new_tag = match kind {

View file

@ -0,0 +1,6 @@
// error-pattern: pointer must be in-bounds
fn main() { unsafe {
let ptr = Box::into_raw(Box::new(0u16));
Box::from_raw(ptr as *mut u32);
} }

View file

@ -0,0 +1,7 @@
// error-pattern: dangling pointer was dereferenced
use std::ptr::NonNull;
fn main() { unsafe {
let ptr = NonNull::<i32>::dangling();
Box::from_raw(ptr.as_ptr());
} }