factor wide ptr metadata checking into separate method

also fat -> wide
This commit is contained in:
Ralf Jung 2019-08-25 13:57:46 +02:00
parent 783469ca09
commit 92e75c0f88
2 changed files with 48 additions and 39 deletions

View File

@ -11,7 +11,7 @@ use std::hash::Hash;
use super::{
GlobalAlloc, InterpResult,
OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
Scalar, OpTy, Machine, InterpCx, ValueVisitor, MPlaceTy,
};
macro_rules! throw_validation_failure {
@ -250,6 +250,44 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
self.path.truncate(path_len);
Ok(())
}
fn check_wide_ptr_meta(
&mut self,
meta: Option<Scalar<M::PointerTag>>,
pointee: TyLayout<'tcx>,
) -> InterpResult<'tcx> {
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(pointee.ty, self.ecx.param_env);
match tail.sty {
ty::Dynamic(..) => {
let vtable = meta.unwrap();
try_validation!(
self.ecx.memory.check_ptr_access(
vtable,
3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
self.ecx.tcx.data_layout.pointer_align.abi,
),
"dangling or unaligned vtable pointer in wide pointer or too small vtable",
self.path
);
try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
"invalid drop fn in vtable", self.path);
try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
"invalid size or align in vtable", self.path);
// FIXME: More checks for the vtable.
}
ty::Slice(..) | ty::Str => {
try_validation!(meta.unwrap().to_usize(self.ecx),
"non-integer slice length in wide pointer", self.path);
}
ty::Foreign(..) => {
// Unsized, but not wide.
}
_ =>
bug!("Unexpected unsized type tail: {:?}", tail),
}
Ok(())
}
}
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>
}
}
_ if ty.is_box() || ty.is_region_ptr() => {
// Handle fat pointers.
// Handle wide pointers.
// Check metadata early, for better diagnostics
let ptr = try_validation!(value.to_scalar_ptr(),
"undefined address in pointer", self.path);
let meta = try_validation!(value.to_meta(),
"uninitialized data in fat pointer metadata", self.path);
"uninitialized data in wide pointer metadata", self.path);
let layout = self.ecx.layout_of(value.layout.ty.builtin_deref(true).unwrap().ty)?;
if layout.is_unsized() {
let tail = self.ecx.tcx.struct_tail_erasing_lifetimes(layout.ty,
self.ecx.param_env);
match tail.sty {
ty::Dynamic(..) => {
let vtable = meta.unwrap();
try_validation!(
self.ecx.memory.check_ptr_access(
vtable,
3*self.ecx.tcx.data_layout.pointer_size, // drop, size, align
self.ecx.tcx.data_layout.pointer_align.abi,
),
"dangling or unaligned vtable pointer or too small vtable",
self.path
);
try_validation!(self.ecx.read_drop_type_from_vtable(vtable),
"invalid drop fn in vtable", self.path);
try_validation!(self.ecx.read_size_and_align_from_vtable(vtable),
"invalid size or align in vtable", self.path);
// FIXME: More checks for the vtable.
}
ty::Slice(..) | ty::Str => {
try_validation!(meta.unwrap().to_usize(self.ecx),
"non-integer slice length in fat pointer", self.path);
}
ty::Foreign(..) => {
// Unsized, but not fat.
}
_ =>
bug!("Unexpected unsized type tail: {:?}", tail),
}
self.check_wide_ptr_meta(meta, layout)?;
}
// Make sure this is dereferencable and all.
let (size, align) = self.ecx.size_and_align_of(meta, layout)?

View File

@ -10,7 +10,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/union-ub-fat-ptr.rs:81:1
|
LL | const C: &str = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.str};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
|
= 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
@ -18,7 +18,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/union-ub-fat-ptr.rs:84:1
|
LL | const C2: &MyStr = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.my_str};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
|
= 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
@ -34,7 +34,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/union-ub-fat-ptr.rs:93:1
|
LL | const C3: &[u8] = unsafe { SliceTransmute { bad: BadSliceRepr { ptr: &42, len: &3 } }.slice};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in fat pointer
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered non-integer slice length in wide pointer
|
= 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
@ -42,7 +42,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/union-ub-fat-ptr.rs:97:1
|
LL | const D: &dyn Trait = unsafe { DynTransmute { repr: DynRepr { ptr: &92, vtable: &3 } }.rust};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
|
= 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
@ -50,7 +50,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/union-ub-fat-ptr.rs:100:1
|
LL | const E: &dyn Trait = unsafe { DynTransmute { repr2: DynRepr2 { ptr: &92, vtable: &3 } }.rust};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
|
= 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
@ -58,7 +58,7 @@ error[E0080]: it is undefined behavior to use this value
--> $DIR/union-ub-fat-ptr.rs:103:1
|
LL | const F: &dyn Trait = unsafe { DynTransmute { bad: BadDynRepr { ptr: &92, vtable: 3 } }.rust};
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer or too small vtable
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered dangling or unaligned vtable pointer in wide pointer or too small vtable
|
= 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