interpret: better error message for out-of-bounds pointer arithmetic and accesses
This commit is contained in:
@@ -349,7 +349,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
|
||||
// Check that the memory between them is dereferenceable at all, starting from the
|
||||
// origin pointer: `dist` is `a - b`, so it is based on `b`.
|
||||
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::OffsetFromTest)
|
||||
self.check_ptr_access_signed(b, dist, CheckInAllocMsg::Dereferenceable)
|
||||
.map_err_kind(|_| {
|
||||
// This could mean they point to different allocations, or they point to the same allocation
|
||||
// but not the entire range between the pointers is in-bounds.
|
||||
@@ -373,7 +373,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self.check_ptr_access_signed(
|
||||
a,
|
||||
dist.checked_neg().unwrap(), // i64::MIN is impossible as no allocation can be that large
|
||||
CheckInAllocMsg::OffsetFromTest,
|
||||
CheckInAllocMsg::Dereferenceable,
|
||||
)
|
||||
.map_err_kind(|_| {
|
||||
// Make the error more specific.
|
||||
@@ -652,7 +652,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
offset_bytes: i64,
|
||||
) -> InterpResult<'tcx, Pointer<Option<M::Provenance>>> {
|
||||
// The offset must be in bounds starting from `ptr`.
|
||||
self.check_ptr_access_signed(ptr, offset_bytes, CheckInAllocMsg::PointerArithmeticTest)?;
|
||||
self.check_ptr_access_signed(
|
||||
ptr,
|
||||
offset_bytes,
|
||||
CheckInAllocMsg::InboundsPointerArithmetic,
|
||||
)?;
|
||||
// This also implies that there is no overflow, so we are done.
|
||||
interp_ok(ptr.wrapping_signed_offset(offset_bytes, self))
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
kind = "static_mem"
|
||||
)
|
||||
}
|
||||
None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccessTest)),
|
||||
None => err_ub!(PointerUseAfterFree(alloc_id, CheckInAllocMsg::MemoryAccess)),
|
||||
})
|
||||
.into();
|
||||
};
|
||||
@@ -414,10 +414,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self,
|
||||
ptr,
|
||||
size,
|
||||
CheckInAllocMsg::MemoryAccessTest,
|
||||
CheckInAllocMsg::MemoryAccess,
|
||||
|this, alloc_id, offset, prov| {
|
||||
let (size, align) = this
|
||||
.get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccessTest)?;
|
||||
let (size, align) =
|
||||
this.get_live_alloc_size_and_align(alloc_id, CheckInAllocMsg::MemoryAccess)?;
|
||||
interp_ok((size, align, (alloc_id, offset, prov)))
|
||||
},
|
||||
)
|
||||
@@ -613,7 +613,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
}
|
||||
Some(GlobalAlloc::Function { .. }) => throw_ub!(DerefFunctionPointer(id)),
|
||||
Some(GlobalAlloc::VTable(..)) => throw_ub!(DerefVTablePointer(id)),
|
||||
None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccessTest)),
|
||||
None => throw_ub!(PointerUseAfterFree(id, CheckInAllocMsg::MemoryAccess)),
|
||||
Some(GlobalAlloc::Static(def_id)) => {
|
||||
assert!(self.tcx.is_static(def_id));
|
||||
// Thread-local statics do not have a constant address. They *must* be accessed via
|
||||
@@ -707,7 +707,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self,
|
||||
ptr,
|
||||
size_i64,
|
||||
CheckInAllocMsg::MemoryAccessTest,
|
||||
CheckInAllocMsg::MemoryAccess,
|
||||
|this, alloc_id, offset, prov| {
|
||||
let alloc = this.get_alloc_raw(alloc_id)?;
|
||||
interp_ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc)))
|
||||
@@ -809,7 +809,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
self,
|
||||
ptr,
|
||||
size_i64,
|
||||
CheckInAllocMsg::MemoryAccessTest,
|
||||
CheckInAllocMsg::MemoryAccess,
|
||||
|this, alloc_id, offset, prov| {
|
||||
let (alloc, machine) = this.get_alloc_raw_mut(alloc_id)?;
|
||||
interp_ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc, machine)))
|
||||
@@ -1615,7 +1615,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
|
||||
err_ub!(DanglingIntPointer {
|
||||
addr: offset,
|
||||
inbounds_size: size,
|
||||
msg: CheckInAllocMsg::InboundsTest
|
||||
msg: CheckInAllocMsg::Dereferenceable
|
||||
})
|
||||
})
|
||||
.into()
|
||||
|
||||
@@ -510,7 +510,7 @@ impl<'rt, 'tcx, M: Machine<'tcx>> ValidityVisitor<'rt, 'tcx, M> {
|
||||
self.ecx.check_ptr_access(
|
||||
place.ptr(),
|
||||
size,
|
||||
CheckInAllocMsg::InboundsTest, // will anyway be replaced by validity message
|
||||
CheckInAllocMsg::Dereferenceable, // will anyway be replaced by validity message
|
||||
),
|
||||
self.path,
|
||||
Ub(DanglingIntPointer { addr: 0, .. }) => NullPtr { ptr_kind },
|
||||
|
||||
Reference in New Issue
Block a user