rename InvalidIntPtrUsage
This commit is contained in:
parent
2feeb88b62
commit
707bd7b213
9 changed files with 54 additions and 50 deletions
|
|
@ -1,4 +1,4 @@
|
|||
use super::{AllocId, CheckInAllocMsg, Pointer, RawConst, ScalarMaybeUndef};
|
||||
use super::{AllocId, Pointer, RawConst, ScalarMaybeUndef};
|
||||
|
||||
use crate::mir::interpret::ConstValue;
|
||||
use crate::ty::layout::LayoutError;
|
||||
|
|
@ -304,6 +304,32 @@ impl fmt::Display for InvalidProgramInfo<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Details of why a pointer had to be in-bounds.
|
||||
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum CheckInAllocMsg {
|
||||
MemoryAccessTest,
|
||||
NullPointerTest,
|
||||
PointerArithmeticTest,
|
||||
InboundsTest,
|
||||
}
|
||||
|
||||
impl fmt::Display for CheckInAllocMsg {
|
||||
/// When this is printed as an error the context looks like this
|
||||
/// "{test name} failed: pointer must be in-bounds at offset..."
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match *self {
|
||||
CheckInAllocMsg::MemoryAccessTest => "memory access",
|
||||
CheckInAllocMsg::NullPointerTest => "NULL pointer test",
|
||||
CheckInAllocMsg::PointerArithmeticTest => "pointer arithmetic",
|
||||
CheckInAllocMsg::InboundsTest => "inbounds test",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Error information for when the program caused Undefined Behavior.
|
||||
pub enum UndefinedBehaviorInfo {
|
||||
/// Free-form case. Only for errors that are never caught!
|
||||
|
|
@ -333,17 +359,15 @@ pub enum UndefinedBehaviorInfo {
|
|||
msg: CheckInAllocMsg,
|
||||
allocation_size: Size,
|
||||
},
|
||||
/// Using an integer as a pointer in the wrong way.
|
||||
DanglingIntPointer(u64, CheckInAllocMsg),
|
||||
/// Used a pointer with bad alignment.
|
||||
AlignmentCheckFailed {
|
||||
required: Align,
|
||||
has: Align,
|
||||
},
|
||||
/// Using an integer as a pointer in the wrong way.
|
||||
InvalidIntPointerUsage(u64),
|
||||
/// Writing to read-only memory.
|
||||
WriteToReadOnly(AllocId),
|
||||
/// Using a pointer-not-to-a-function as function pointer.
|
||||
InvalidFunctionPointer(Pointer),
|
||||
// Trying to access the data behind a function pointer.
|
||||
DerefFunctionPointer(AllocId),
|
||||
/// The value validity check found a problem.
|
||||
|
|
@ -356,6 +380,8 @@ pub enum UndefinedBehaviorInfo {
|
|||
InvalidChar(u32),
|
||||
/// An enum discriminant was set to a value which was outside the range of valid values.
|
||||
InvalidDiscriminant(ScalarMaybeUndef),
|
||||
/// Using a pointer-not-to-a-function as function pointer.
|
||||
InvalidFunctionPointer(Pointer),
|
||||
/// Using uninitialized data where it is not allowed.
|
||||
InvalidUndefBytes(Option<Pointer>),
|
||||
/// Working with a local that is not currently live.
|
||||
|
|
@ -397,8 +423,12 @@ impl fmt::Display for UndefinedBehaviorInfo {
|
|||
ptr.alloc_id,
|
||||
allocation_size.bytes()
|
||||
),
|
||||
InvalidIntPointerUsage(0) => write!(f, "dereferencing NULL pointer"),
|
||||
InvalidIntPointerUsage(i) => write!(f, "dereferencing dangling pointer to 0x{:x}", i),
|
||||
DanglingIntPointer(_, CheckInAllocMsg::NullPointerTest) => {
|
||||
write!(f, "NULL pointer is not allowed for this operation")
|
||||
}
|
||||
DanglingIntPointer(i, msg) => {
|
||||
write!(f, "{} failed: 0x{:x} is not a valid pointer", msg, i)
|
||||
}
|
||||
AlignmentCheckFailed { required, has } => write!(
|
||||
f,
|
||||
"accessing memory with alignment {}, but alignment {} is required",
|
||||
|
|
@ -406,14 +436,14 @@ impl fmt::Display for UndefinedBehaviorInfo {
|
|||
required.bytes()
|
||||
),
|
||||
WriteToReadOnly(a) => write!(f, "writing to {} which is read-only", a),
|
||||
InvalidFunctionPointer(p) => {
|
||||
write!(f, "using {} as function pointer but it does not point to a function", p)
|
||||
}
|
||||
DerefFunctionPointer(a) => write!(f, "accessing {} which contains a function", a),
|
||||
ValidationFailure(ref err) => write!(f, "type validation failed: {}", err),
|
||||
InvalidBool(b) => write!(f, "interpreting an invalid 8-bit value as a bool: {}", b),
|
||||
InvalidChar(c) => write!(f, "interpreting an invalid 32-bit value as a char: {}", c),
|
||||
InvalidDiscriminant(val) => write!(f, "enum value has invalid discriminant: {}", val),
|
||||
InvalidFunctionPointer(p) => {
|
||||
write!(f, "using {} as function pointer but it does not point to a function", p)
|
||||
}
|
||||
InvalidUndefBytes(Some(p)) => write!(
|
||||
f,
|
||||
"reading uninitialized memory at {}, but this operation requires initialized memory",
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ use crate::ty::subst::GenericArgKind;
|
|||
use crate::ty::{self, Instance, Ty, TyCtxt};
|
||||
|
||||
pub use self::error::{
|
||||
struct_error, ConstEvalErr, ConstEvalRawResult, ConstEvalResult, ErrorHandled, FrameInfo,
|
||||
InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, MachineStopType,
|
||||
struct_error, CheckInAllocMsg, ConstEvalErr, ConstEvalRawResult, ConstEvalResult, ErrorHandled,
|
||||
FrameInfo, InterpError, InterpErrorInfo, InterpResult, InvalidProgramInfo, MachineStopType,
|
||||
ResourceExhaustionInfo, UndefinedBehaviorInfo, UnsupportedOpInfo,
|
||||
};
|
||||
|
||||
|
|
@ -126,7 +126,7 @@ pub use self::value::{get_slice_bytes, ConstValue, RawConst, Scalar, ScalarMaybe
|
|||
|
||||
pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
|
||||
|
||||
pub use self::pointer::{CheckInAllocMsg, Pointer, PointerArithmetic};
|
||||
pub use self::pointer::{Pointer, PointerArithmetic};
|
||||
|
||||
/// Uniquely identifies one of the following:
|
||||
/// - A constant
|
||||
|
|
|
|||
|
|
@ -4,33 +4,7 @@ use rustc_macros::HashStable;
|
|||
use rustc_target::abi::{HasDataLayout, Size};
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
/// Used by `check_in_alloc` to indicate context of check
|
||||
#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable, HashStable)]
|
||||
pub enum CheckInAllocMsg {
|
||||
MemoryAccessTest,
|
||||
NullPointerTest,
|
||||
PointerArithmeticTest,
|
||||
InboundsTest,
|
||||
}
|
||||
|
||||
impl Display for CheckInAllocMsg {
|
||||
/// When this is printed as an error the context looks like this
|
||||
/// "{test name} failed: pointer must be in-bounds at offset..."
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match *self {
|
||||
CheckInAllocMsg::MemoryAccessTest => "Memory access",
|
||||
CheckInAllocMsg::NullPointerTest => "Null pointer test",
|
||||
CheckInAllocMsg::PointerArithmeticTest => "Pointer arithmetic",
|
||||
CheckInAllocMsg::InboundsTest => "Inbounds test",
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
use std::fmt;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Pointer arithmetic
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ use rustc_middle::ty::{self, Ty};
|
|||
use rustc_span::def_id::DefId;
|
||||
|
||||
use super::{
|
||||
AllocId, Allocation, AllocationExtra, Frame, ImmTy, InterpCx, InterpResult, Memory, MemoryKind,
|
||||
OpTy, Operand, PlaceTy, Pointer, Scalar,
|
||||
AllocId, Allocation, AllocationExtra, CheckInAllocMsg, Frame, ImmTy, InterpCx, InterpResult,
|
||||
Memory, MemoryKind, OpTy, Operand, PlaceTy, Pointer, Scalar,
|
||||
};
|
||||
|
||||
/// Data returned by Machine::stack_pop,
|
||||
|
|
@ -346,7 +346,7 @@ pub trait Machine<'mir, 'tcx>: Sized {
|
|||
) -> InterpResult<'tcx, Pointer<Self::PointerTag>> {
|
||||
Err((if int == 0 {
|
||||
// This is UB, seriously.
|
||||
err_ub!(InvalidIntPointerUsage(0))
|
||||
err_ub!(DanglingIntPointer(0, CheckInAllocMsg::InboundsTest))
|
||||
} else {
|
||||
// This is just something we cannot support during const-eval.
|
||||
err_unsup!(ReadBytesAsPointer)
|
||||
|
|
|
|||
|
|
@ -365,7 +365,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
|
|||
assert!(size.bytes() == 0);
|
||||
// Must be non-NULL.
|
||||
if bits == 0 {
|
||||
throw_ub!(InvalidIntPointerUsage(0))
|
||||
throw_ub!(DanglingIntPointer(0, msg))
|
||||
}
|
||||
// Must be aligned.
|
||||
if let Some(align) = align {
|
||||
|
|
|
|||
|
|
@ -360,10 +360,10 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||
place.ptr, size, align
|
||||
);
|
||||
match err.kind {
|
||||
err_ub!(InvalidIntPointerUsage(0)) => {
|
||||
err_ub!(DanglingIntPointer(0, _)) => {
|
||||
throw_validation_failure!(format_args!("a NULL {}", kind), self.path)
|
||||
}
|
||||
err_ub!(InvalidIntPointerUsage(i)) => throw_validation_failure!(
|
||||
err_ub!(DanglingIntPointer(i, _)) => throw_validation_failure!(
|
||||
format_args!("a {} to unallocated address {}", kind, i),
|
||||
self.path
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ LL | / const OUT_OF_BOUNDS_PTR: NonNull<u8> = { unsafe {
|
|||
LL | | let ptr: &[u8; 256] = mem::transmute(&0u8); // &0 gets promoted so it does not dangle
|
||||
LL | | // Use address-of-element for pointer arithmetic. This could wrap around to NULL!
|
||||
LL | | let out_of_bounds_ptr = &ptr[255];
|
||||
| | ^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc11 which has size 1
|
||||
| | ^^^^^^^^^ memory access failed: pointer must be in-bounds at offset 256, but is outside bounds of alloc11 which has size 1
|
||||
LL | | mem::transmute(out_of_bounds_ptr)
|
||||
LL | | } };
|
||||
| |____-
|
||||
|
|
|
|||
|
|
@ -186,13 +186,13 @@ error[E0080]: could not evaluate static initializer
|
|||
--> $DIR/ub-wide-ptr.rs:121:5
|
||||
|
|
||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, 0usize))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ dereferencing NULL pointer
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ inbounds test failed: 0x0 is not a valid pointer
|
||||
|
||||
error[E0080]: could not evaluate static initializer
|
||||
--> $DIR/ub-wide-ptr.rs:125:5
|
||||
|
|
||||
LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64))
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ memory access failed: pointer must be in-bounds at offset N, but is outside bounds of allocN which has size N
|
||||
|
||||
error: aborting due to 24 previous errors
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ error: any use of this value will cause an error
|
|||
LL | intrinsics::ptr_offset_from(self, origin)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| |
|
||||
| dereferencing NULL pointer
|
||||
| inbounds test failed: 0x0 is not a valid pointer
|
||||
| inside `std::ptr::const_ptr::<impl *const u8>::offset_from` at $SRC_DIR/libcore/ptr/const_ptr.rs:LL:COL
|
||||
| inside `OFFSET_FROM_NULL` at $DIR/offset_from_ub.rs:37:14
|
||||
|
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue