Skip to content

Commit 2e20cae

Browse files
committed
Auto merge of rust-lang#2319 - RalfJung:dont-touch-vtables, r=RalfJung
fix retagging of vtable ptrs Fixes a problem reported by `@saethlin` on [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/269128-miri/topic/Stacked.20Borrows.20field.20retagging/near/288040048).
2 parents 8d53314 + a4e7e1e commit 2e20cae

File tree

2 files changed

+19
-0
lines changed

2 files changed

+19
-0
lines changed

src/stacked_borrows.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
10391039
let val = self.ecx.read_immediate(&place.into())?;
10401040
let val = self.ecx.retag_reference(&val, mutbl, protector)?;
10411041
self.ecx.write_immediate(*val, &place.into())?;
1042+
} else if matches!(place.layout.ty.kind(), ty::RawPtr(..)) {
1043+
// Wide raw pointers *do* have fields and their types are strange.
1044+
// vtables have a type like `&[*const (); 3]` or so!
1045+
// Do *not* recurse into them.
1046+
// (No need to worry about wide references or boxes, those always "qualify".)
10421047
} else {
10431048
// Maybe we need to go deeper.
10441049
self.walk_value(place)?;

tests/pass/stacked-borrows/stacked-borrows.rs

+14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// compile-flags: -Zmiri-retag-fields
2+
#![feature(allocator_api)]
23
use std::ptr;
34

45
// Test various stacked-borrows-related things.
@@ -17,6 +18,7 @@ fn main() {
1718
raw_ref_to_part();
1819
array_casts();
1920
mut_below_shr();
21+
wide_raw_ptr_in_tuple();
2022
}
2123

2224
// Make sure that reading from an `&mut` does, like reborrowing to `&`,
@@ -205,3 +207,15 @@ fn mut_below_shr() {
205207
let r = &**p;
206208
let _val = *r;
207209
}
210+
211+
fn wide_raw_ptr_in_tuple() {
212+
let mut x: Box<dyn std::any::Any> = Box::new("ouch");
213+
let r = &mut *x as *mut dyn std::any::Any;
214+
// This triggers the visitor-based recursive retagging. It is *not* supposed to retag raw
215+
// pointers, but then the visitor might recurse into the "fields" of a wide raw pointer and
216+
// finds a reference (to a vtable) there that it wants to retag... and that would be Wrong.
217+
let pair = (r, &0);
218+
let r = unsafe { &mut *pair.0 };
219+
// Make sure the fn ptr part of the vtable is still fine.
220+
r.type_id();
221+
}

0 commit comments

Comments
 (0)