about summary refs log tree commit diff
path: root/src/librustc
diff options
context:
space:
mode:
authorRalf Jung <post@ralfj.de>2018-11-12 11:22:18 +0100
committerRalf Jung <post@ralfj.de>2018-11-15 10:59:39 +0100
commita3770c2547dd163e0f5bfa07ec23b8b461fbe145 (patch)
tree443dbaacb2e1f5fab6479d0958fbc1cef1d7027f /src/librustc
parentffb6ba082897db55f7ab4e576175b144597aa38f (diff)
downloadrust-a3770c2547dd163e0f5bfa07ec23b8b461fbe145.tar.gz
rust-a3770c2547dd163e0f5bfa07ec23b8b461fbe145.zip
do not accept out-of-bounds pointers in enum discriminants, they might be NULL
Diffstat (limited to 'src/librustc')
-rw-r--r--src/librustc/ich/impls_ty.rs7
-rw-r--r--src/librustc/mir/interpret/allocation.rs8
-rw-r--r--src/librustc/mir/interpret/error.rs14
-rw-r--r--src/librustc/mir/interpret/mod.rs2
4 files changed, 24 insertions, 7 deletions
diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs
index f3a62975dd9..9c1fb99cb73 100644
--- a/src/librustc/ich/impls_ty.rs
+++ b/src/librustc/ich/impls_ty.rs
@@ -451,7 +451,7 @@ impl_stable_hash_for!(
         FunctionRetMismatch(a, b),
         NoMirFor(s),
         UnterminatedCString(ptr),
-        PointerOutOfBounds { ptr, access, allocation_size },
+        PointerOutOfBounds { ptr, check, allocation_size },
         InvalidBoolOp(bop),
         Unimplemented(s),
         BoundsCheck { len, index },
@@ -471,6 +471,11 @@ impl_stable_hash_for!(
     }
 );
 
+impl_stable_hash_for!(enum mir::interpret::InboundsCheck {
+    Live,
+    MaybeDead
+});
+
 impl_stable_hash_for!(enum mir::interpret::Lock {
     NoLock,
     WriteLock(dl),
diff --git a/src/librustc/mir/interpret/allocation.rs b/src/librustc/mir/interpret/allocation.rs
index cc92b63256c..02c0ebcec4f 100644
--- a/src/librustc/mir/interpret/allocation.rs
+++ b/src/librustc/mir/interpret/allocation.rs
@@ -19,6 +19,14 @@ use mir;
 use std::ops::{Deref, DerefMut};
 use rustc_data_structures::sorted_map::SortedMap;
 
+/// Used by `check_bounds` to indicate whether the pointer needs to be just inbounds
+/// or also inbounds of a *live* allocation.
+#[derive(Debug, Copy, Clone, RustcEncodable, RustcDecodable)]
+pub enum InboundsCheck {
+    Live,
+    MaybeDead,
+}
+
 #[derive(Clone, Debug, Eq, PartialEq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
 pub struct Allocation<Tag=(),Extra=()> {
     /// The actual bytes of the allocation.
diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs
index c51a655418c..bf678db51c9 100644
--- a/src/librustc/mir/interpret/error.rs
+++ b/src/librustc/mir/interpret/error.rs
@@ -15,7 +15,7 @@ use ty::{Ty, layout};
 use ty::layout::{Size, Align, LayoutError};
 use rustc_target::spec::abi::Abi;
 
-use super::{Pointer, ScalarMaybeUndef};
+use super::{Pointer, InboundsCheck, ScalarMaybeUndef};
 
 use backtrace::Backtrace;
 
@@ -243,7 +243,7 @@ pub enum EvalErrorKind<'tcx, O> {
     InvalidDiscriminant(ScalarMaybeUndef),
     PointerOutOfBounds {
         ptr: Pointer,
-        access: bool,
+        check: InboundsCheck,
         allocation_size: Size,
     },
     InvalidNullPointerUsage,
@@ -457,9 +457,13 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for EvalErrorKind<'tcx, O> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         use self::EvalErrorKind::*;
         match *self {
-            PointerOutOfBounds { ptr, access, allocation_size } => {
-                write!(f, "{} at offset {}, outside bounds of allocation {} which has size {}",
-                       if access { "memory access" } else { "pointer computed" },
+            PointerOutOfBounds { ptr, check, allocation_size } => {
+                write!(f, "Pointer must be in-bounds{} at offset {}, but is outside bounds of \
+                           allocation {} which has size {}",
+                       match check {
+                           InboundsCheck::Live => " and live",
+                           InboundsCheck::MaybeDead => "",
+                       },
                        ptr.offset.bytes(), ptr.alloc_id, allocation_size.bytes())
             },
             ValidationFailure(ref err) => {
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index 40daf78f546..ec25431bd1f 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -28,7 +28,7 @@ pub use self::error::{
 pub use self::value::{Scalar, ConstValue, ScalarMaybeUndef};
 
 pub use self::allocation::{
-    Allocation, AllocationExtra,
+    InboundsCheck, Allocation, AllocationExtra,
     Relocations, UndefMask,
 };