mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-03 20:23:59 +00:00
factor wide ptr metadata checking into separate method
also fat -> wide
This commit is contained in:
parent
783469ca09
commit
92e75c0f88
@ -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)?
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user