Skip to content

Commit 92e75c0

Browse files
committed
factor wide ptr metadata checking into separate method
also fat -> wide
1 parent 783469c commit 92e75c0

File tree

2 files changed

+48
-39
lines changed

2 files changed

+48
-39
lines changed

src/librustc_mir/interpret/validity.rs

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use std::hash::Hash;
1111

1212
use super::{
1313
GlobalAlloc, InterpResult,
14-
OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
14+
Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
1515
};
1616

1717
macro_rules! throw_validation_failure {
@@ -250,6 +250,44 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
250250
self.path.truncate(path_len);
251251
Ok(())
252252
}
253+
254+
fn check_wide_ptr_meta(
255+
&mut self,
256+
meta: Option<Scalar<M::PointerTag>>,
257+
pointee: TyLayout<'tcx>,
258+
) -> InterpResult<'tcx> {
259+
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
260+
match tail.sty {
261+
ty::Dynamic(..) => {
262+
let vtable = meta.unwrap();
263+
try_validation!(
264+
self.ecx.memory.check_ptr_access(
265+
vtable,
266+
3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
267+
self.ecx.tcx.data_layout.pointer_align.abi,
268+
),
269+
"dangling or unaligned vtable pointer in wide pointer or too small vtable",
270+
self.path
271+
);
272+
try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
273+
"invalid drop fn in vtable", self.path);
274+
try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
275+
"invalid size or align in vtable", self.path);
276+
// FIXME: More checks for the vtable.
277+
}
278+
ty::Slice(..) | ty::Str => {
279+
try_validation!(meta.unwrap().to_usize(self.ecx),
280+
"non-integer slice length in wide pointer", self.path);
281+
}
282+
ty::Foreign(..) => {
283+
// Unsized, but not wide.
284+
}
285+
_ =>
286+
bug!("Unexpected unsized type tail: {:?}", tail),
287+
}
288+
289+
Ok(())
290+
}
253291
}
254292

255293
impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
@@ -353,44 +391,15 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
353391
}
354392
}
355393
_ if ty.is_box() || ty.is_region_ptr() => {
356-
// Handle fat pointers.
394+
// Handle wide pointers.
357395
// Check metadata early, for better diagnostics
358396
let ptr = try_validation!(value.to_scalar_ptr(),
359397
"undefined address in pointer", self.path);
360398
let meta = try_validation!(value.to_meta(),
361-
"uninitialized data in fat pointer metadata", self.path);
399+
"uninitialized data in wide pointer metadata", self.path);
362400
let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
363401
if layout.is_unsized() {
364-
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(layout.ty,
365-
self.ecx.param_env);
366-
match tail.sty {
367-
ty::Dynamic(..) => {
368-
let vtable = meta.unwrap();
369-
try_validation!(
370-
self.ecx.memory.check_ptr_access(
371-
vtable,
372-
3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
373-
self.ecx.tcx.data_layout.pointer_align.abi,
374-
),
375-
"dangling or unaligned vtable pointer or too small vtable",
376-
self.path
377-
);
378-
try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
379-
"invalid drop fn in vtable", self.path);
380-
try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
381-
"invalid size or align in vtable", self.path);
382-
// FIXME: More checks for the vtable.
383-
}
384-
ty::Slice(..) | ty::Str => {
385-
try_validation!(meta.unwrap().to_usize(self.ecx),
386-
"non-integer slice length in fat pointer", self.path);
387-
}
388-
ty::Foreign(..) => {
389-
// Unsized, but not fat.
390-
}
391-
_ =>
392-
bug!("Unexpected unsized type tail: {:?}", tail),
393-
}
402+
self.check_wide_ptr_meta(meta, layout)?;
394403
}
395404
// Make sure this is dereferencable and all.
396405
let (size, align) = self.ecx.size_and_align_of(meta, layout)?

src/test/ui/consts/const-eval/union-ub-fat-ptr.stderr

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ error[E0080]: it is undefined behavior to use this value
1010
--> $DIR/union-ub-fat-ptr.rs:81:1
1111
|
1212
LL | const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
13-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
13+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
1414
|
1515
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
1616

1717
error[E0080]: it is undefined behavior to use this value
1818
--> $DIR/union-ub-fat-ptr.rs:84:1
1919
|
2020
LL | const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
21-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
21+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
2222
|
2323
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
2424

@@ -34,31 +34,31 @@ error[E0080]: it is undefined behavior to use this value
3434
--> $DIR/union-ub-fat-ptr.rs:93:1
3535
|
3636
LL | const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
37-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
37+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
3838
|
3939
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4040

4141
error[E0080]: it is undefined behavior to use this value
4242
--> $DIR/union-ub-fat-ptr.rs:97:1
4343
|
4444
LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
45-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
45+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
4646
|
4747
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
4848

4949
error[E0080]: it is undefined behavior to use this value
5050
--> $DIR/union-ub-fat-ptr.rs:100:1
5151
|
5252
LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
53-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
53+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
5454
|
5555
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
5656

5757
error[E0080]: it is undefined behavior to use this value
5858
--> $DIR/union-ub-fat-ptr.rs:103:1
5959
|
6060
LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
61-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
61+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
6262
|
6363
= note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
6464

0 commit comments

Comments
 (0)