]> git.lizzy.rs Git - rust.git/commitdiff
Fix potential integer overflow in SGX memory range calculation.
authorJethro Beekman <jethro@fortanix.com>
Fri, 3 May 2019 01:15:44 +0000 (18:15 -0700)
committerJethro Beekman <jethro@fortanix.com>
Fri, 3 May 2019 01:15:44 +0000 (18:15 -0700)
Thanks to Eduard Marin and David Oswald at the University of Burmingham,
and Jo Van Bulck at KU Leuven for discovering this issue.

src/libstd/sys/sgx/abi/mem.rs
src/libstd/sys/sgx/abi/usercalls/alloc.rs

index 808f1ce3ff2c73a4265f9d60319357505de2a425..d9051733da24dace89662b70f3fd479bdfbfc1a8 100644 (file)
@@ -27,19 +27,23 @@ pub fn image_base() -> u64 {
 }
 
 /// Returns `true` if the specified memory range is in the enclave.
+///
+/// `p + len` must not overflow.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn is_enclave_range(p: *const u8, len: usize) -> bool {
-    let start=p as u64;
-    let end=start + (len as u64);
+    let start = p as u64;
+    let end = start + (len as u64);
     start >= image_base() &&
         end <= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant
 }
 
 /// Returns `true` if the specified memory range is in userspace.
+///
+/// `p + len` must not overflow.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub fn is_user_range(p: *const u8, len: usize) -> bool {
-    let start=p as u64;
-    let end=start + (len as u64);
+    let start = p as u64;
+    let end = start + (len as u64);
     end <= image_base() ||
         start >= image_base() + (unsafe { ENCLAVE_SIZE } as u64) // unsafe ok: link-time constant
 }
index 38e05f6fd2757a4816eb083ed8277835176bdfa9..c9ff53d0a4fd656497a932681dba9cb0ead346fc 100644 (file)
@@ -85,8 +85,10 @@ pub unsafe trait UserSafe {
     ///
     /// * the pointer is not aligned.
     /// * the pointer is null.
+    /// * the pointed-to range does not fit in the address space.
     /// * the pointed-to range is not in user memory.
     unsafe fn from_raw_sized(ptr: *mut u8, size: usize) -> NonNull<Self> {
+        assert!(ptr.wrapping_add(size) >= ptr);
         let ret = Self::from_raw_sized_unchecked(ptr, size);
         Self::check_ptr(ret);
         NonNull::new_unchecked(ret as _)
@@ -268,6 +270,7 @@ pub fn uninitialized(n: usize) -> Self {
     ///
     /// * The pointer is not aligned
     /// * The pointer is null
+    /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
         User(NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>())))
@@ -372,6 +375,7 @@ impl<T> UserRef<[T]> where [T]: UserSafe {
     ///
     /// * The pointer is not aligned
     /// * The pointer is null
+    /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self {
         &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self)
@@ -389,6 +393,7 @@ pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self {
     ///
     /// * The pointer is not aligned
     /// * The pointer is null
+    /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self {
         &mut*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
@@ -552,10 +557,11 @@ impl UserRef<super::raw::ByteBuffer> {
     /// enclave memory.
     ///
     /// # Panics
-    /// This function panics if:
+    /// This function panics if, in the user `ByteBuffer`:
     ///
-    /// * The pointer in the user `ByteBuffer` is null
-    /// * The pointed-to range in the user `ByteBuffer` is not in user memory
+    /// * The pointer is null
+    /// * The pointed-to range does not fit in the address space
+    /// * The pointed-to range is not in user memory
     pub fn copy_user_buffer(&self) -> Vec<u8> {
         unsafe {
             let buf = self.to_enclave();