more precise message for the ptr access check on deref

This commit is contained in:
Ralf Jung 2021-07-14 09:56:54 +02:00
parent 4ff353cd6e
commit ae950a2dc7
6 changed files with 18 additions and 12 deletions

View file

@ -170,6 +170,8 @@ impl fmt::Display for InvalidProgramInfo<'_> {
/// Details of why a pointer had to be in-bounds.
#[derive(Debug, Copy, Clone, TyEncodable, TyDecodable, HashStable)]
pub enum CheckInAllocMsg {
/// We are dereferencing a pointer (i.e., creating a place).
DerefTest,
/// We are access memory.
MemoryAccessTest,
/// We are doing pointer arithmetic.
@ -186,6 +188,7 @@ impl fmt::Display for CheckInAllocMsg {
f,
"{}",
match *self {
CheckInAllocMsg::DerefTest => "dereferencing pointer failed: ",
CheckInAllocMsg::MemoryAccessTest => "memory access failed: ",
CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic failed: ",
CheckInAllocMsg::InboundsTest => "",

View file

@ -428,7 +428,11 @@ crate struct AllocMap<'tcx> {
impl<'tcx> AllocMap<'tcx> {
crate fn new() -> Self {
AllocMap { alloc_map: Default::default(), dedup: Default::default(), next_id: AllocId(NonZeroU64::new(1).unwrap()) }
AllocMap {
alloc_map: Default::default(),
dedup: Default::default(),
next_id: AllocId(NonZeroU64::new(1).unwrap()),
}
}
fn reserve(&mut self) -> AllocId {
let next = self.next_id;

View file

@ -373,7 +373,7 @@ where
let val = self.read_immediate(src)?;
trace!("deref to {} on {:?}", val.layout.ty, *val);
let mplace = self.ref_to_mplace(&val)?;
self.check_mplace_access(mplace)?;
self.check_mplace_access(mplace, CheckInAllocMsg::DerefTest)?;
Ok(mplace)
}
@ -400,18 +400,17 @@ where
}
/// Check if this mplace is dereferencable and sufficiently aligned.
pub fn check_mplace_access(&self, mplace: MPlaceTy<'tcx, M::PointerTag>) -> InterpResult<'tcx> {
fn check_mplace_access(
&self,
mplace: MPlaceTy<'tcx, M::PointerTag>,
msg: CheckInAllocMsg,
) -> InterpResult<'tcx> {
let (size, align) = self
.size_and_align_of_mplace(&mplace)?
.unwrap_or((mplace.layout.size, mplace.layout.align.abi));
assert!(mplace.mplace.align <= align, "dynamic alignment less strict than static one?");
let align = M::enforce_alignment(&self.memory.extra).then_some(align);
self.memory.check_ptr_access_align(
mplace.ptr,
size,
align.unwrap_or(Align::ONE),
CheckInAllocMsg::MemoryAccessTest, // FIXME sth more specific?
)?;
self.memory.check_ptr_access_align(mplace.ptr, size, align.unwrap_or(Align::ONE), msg)?;
Ok(())
}

View file

@ -13,7 +13,7 @@ error[E0080]: evaluation of constant value failed
--> $DIR/ub-nonnull.rs:19:30
|
LL | let out_of_bounds_ptr = &ptr[255];
| ^^^^^^^^ memory access failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1
| ^^^^^^^^ dereferencing pointer failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-nonnull.rs:23:1

View file

@ -13,7 +13,7 @@ error[E0080]: evaluation of constant value failed
--> $DIR/ub-nonnull.rs:19:30
|
LL | let out_of_bounds_ptr = &ptr[255];
| ^^^^^^^^ memory access failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1
| ^^^^^^^^ dereferencing pointer failed: pointer must be in-bounds for 256 bytes at offset 0, but alloc11 has size 1
error[E0080]: it is undefined behavior to use this value
--> $DIR/ub-nonnull.rs:23:1

View file

@ -16,7 +16,7 @@ error[E0080]: evaluation of constant value failed
--> $DIR/ptr_comparisons.rs:64:33
|
LL | unsafe { std::ptr::addr_of!((*(FOO as *const usize as *const [u8; 1000]))[999]) };
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds for 1000 bytes at offset 0, but alloc3 has size $WORD
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing pointer failed: pointer must be in-bounds for 1000 bytes at offset 0, but alloc3 has size $WORD
error: any use of this value will cause an error
--> $DIR/ptr_comparisons.rs:68:27