Skip to content

Commit 1519f04

Browse files
committed
test for upcast detecting bad vtables
1 parent 3f8b399 commit 1519f04

File tree

3 files changed

+75
-19
lines changed

3 files changed

+75
-19
lines changed

src/shims/backtrace.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,15 +123,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
123123

124124
let ptr = this.read_pointer(ptr)?;
125125
// Take apart the pointer, we need its pieces. The offset encodes the span.
126-
let (alloc_id, offset, _tag) = this.ptr_get_alloc_id(ptr)?;
126+
let (alloc_id, offset, _prov) = this.ptr_get_alloc_id(ptr)?;
127127

128128
// This has to be an actual global fn ptr, not a dlsym function.
129-
let fn_instance =
130-
if let Some(GlobalAlloc::Function(instance)) = this.tcx.try_get_global_alloc(alloc_id) {
131-
instance
132-
} else {
133-
throw_ub_format!("expected static function pointer, found {:?}", ptr);
134-
};
129+
let fn_instance = if let Some(GlobalAlloc::Function(instance)) =
130+
this.tcx.try_get_global_alloc(alloc_id)
131+
{
132+
instance
133+
} else {
134+
throw_ub_format!("expected static function pointer, found {:?}", ptr);
135+
};
135136

136137
let lo =
137138
this.tcx.sess.source_map().lookup_char_pos(BytePos(offset.bytes().try_into().unwrap()));

src/stacked_borrows/mod.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -768,13 +768,13 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
768768
drop(global); // don't hold that reference any longer than we have to
769769

770770
let Some((alloc_id, base_offset, orig_tag)) = loc else {
771-
return Ok(());
771+
return Ok(())
772772
};
773773

774774
// The SB history tracking needs a parent tag, so skip if we come from a wildcard.
775775
let ProvenanceExtra::Concrete(orig_tag) = orig_tag else {
776776
// FIXME: should we log this?
777-
return Ok(());
777+
return Ok(())
778778
};
779779

780780
let (_size, _align, kind) = this.get_alloc_info(alloc_id);
@@ -1016,17 +1016,16 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
10161016
fn qualify(ty: ty::Ty<'_>, kind: RetagKind) -> Option<(RefKind, bool)> {
10171017
match ty.kind() {
10181018
// References are simple.
1019-
ty::Ref(_, _, Mutability::Mut) => Some((
1020-
RefKind::Unique { two_phase: kind == RetagKind::TwoPhase },
1021-
kind == RetagKind::FnEntry,
1022-
)),
1023-
ty::Ref(_, _, Mutability::Not) => {
1024-
Some((RefKind::Shared, kind == RetagKind::FnEntry))
1025-
}
1019+
ty::Ref(_, _, Mutability::Mut) =>
1020+
Some((
1021+
RefKind::Unique { two_phase: kind == RetagKind::TwoPhase },
1022+
kind == RetagKind::FnEntry,
1023+
)),
1024+
ty::Ref(_, _, Mutability::Not) =>
1025+
Some((RefKind::Shared, kind == RetagKind::FnEntry)),
10261026
// Raw pointers need to be enabled.
1027-
ty::RawPtr(tym) if kind == RetagKind::Raw => {
1028-
Some((RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, false))
1029-
}
1027+
ty::RawPtr(tym) if kind == RetagKind::Raw =>
1028+
Some((RefKind::Raw { mutable: tym.mutbl == Mutability::Mut }, false)),
10301029
// Boxes are handled separately due to that allocator situation,
10311030
// see the visitor below.
10321031
_ => None,
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#![feature(trait_upcasting)]
2+
#![allow(incomplete_features)]
3+
4+
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
5+
fn a(&self) -> i32 {
6+
10
7+
}
8+
9+
fn z(&self) -> i32 {
10+
11
11+
}
12+
13+
fn y(&self) -> i32 {
14+
12
15+
}
16+
}
17+
18+
trait Bar: Foo {
19+
fn b(&self) -> i32 {
20+
20
21+
}
22+
23+
fn w(&self) -> i32 {
24+
21
25+
}
26+
}
27+
28+
trait Baz: Bar {
29+
fn c(&self) -> i32 {
30+
30
31+
}
32+
}
33+
34+
impl Foo for i32 {
35+
fn a(&self) -> i32 {
36+
100
37+
}
38+
}
39+
40+
impl Bar for i32 {
41+
fn b(&self) -> i32 {
42+
200
43+
}
44+
}
45+
46+
impl Baz for i32 {
47+
fn c(&self) -> i32 {
48+
300
49+
}
50+
}
51+
52+
fn main() {
53+
let baz: &dyn Baz = &1;
54+
let baz_fake: &dyn Bar = unsafe { std::mem::transmute(baz) };
55+
let _: &dyn std::fmt::Debug = baz_fake; //~ERROR upcast on a pointer whose vtable does not match its type
56+
}

0 commit comments

Comments
 (0)