]> git.lizzy.rs Git - rust.git/blobdiff - src/libstd/sys/sgx/abi/usercalls/alloc.rs
Fix potential integer overflow in SGX memory range calculation.
[rust.git] / src / libstd / sys / sgx / abi / usercalls / alloc.rs
index 449a5fe5ae3082a837e1f5d7c744e1bb7228c8a3..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 _)
@@ -190,11 +192,15 @@ fn new_uninit_bytes(size: usize) -> Self {
         unsafe {
             // Mustn't call alloc with size 0.
             let ptr = if size > 0 {
-                super::alloc(size, T::align_of()).expect("User memory allocation failed") as _
+                rtunwrap!(Ok, super::alloc(size, T::align_of())) as _
             } else {
                 T::align_of() as _ // dangling pointer ok for size 0
             };
-            User(NonNull::new_userref(T::from_raw_sized(ptr, size)))
+            if let Ok(v) = crate::panic::catch_unwind(|| T::from_raw_sized(ptr, size)) {
+                User(NonNull::new_userref(v))
+            } else {
+                rtabort!("Got invalid pointer from alloc() usercall")
+            }
         }
     }
 
@@ -264,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>())))
@@ -368,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)
@@ -385,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)
@@ -429,7 +438,7 @@ pub fn to_enclave(&self) -> Vec<T> {
     }
 
     /// Returns an iterator over the slice.
-    pub fn iter(&self) -> Iter<T>
+    pub fn iter(&self) -> Iter<'_, T>
         where T: UserSafe // FIXME: should be implied by [T]: UserSafe?
     {
         unsafe {
@@ -438,7 +447,7 @@ pub fn iter(&self) -> Iter<T>
     }
 
     /// Returns an iterator that allows modifying each value.
-    pub fn iter_mut(&mut self) -> IterMut<T>
+    pub fn iter_mut(&mut self) -> IterMut<'_, T>
         where T: UserSafe // FIXME: should be implied by [T]: UserSafe?
     {
         unsafe {
@@ -519,7 +528,11 @@ impl<T, I: SliceIndex<[T]>> Index<I> for UserRef<[T]> where [T]: UserSafe, I::Ou
     #[inline]
     fn index(&self, index: I) -> &UserRef<I::Output> {
         unsafe {
-            UserRef::from_ptr(index.index(&*self.as_raw_ptr()))
+            if let Some(slice) = index.get(&*self.as_raw_ptr()) {
+                UserRef::from_ptr(slice)
+            } else {
+                rtabort!("index out of range for user slice");
+            }
         }
     }
 }
@@ -529,7 +542,11 @@ impl<T, I: SliceIndex<[T]>> IndexMut<I> for UserRef<[T]> where [T]: UserSafe, I:
     #[inline]
     fn index_mut(&mut self, index: I) -> &mut UserRef<I::Output> {
         unsafe {
-            UserRef::from_mut_ptr(index.index_mut(&mut*self.as_raw_mut_ptr()))
+            if let Some(slice) = index.get_mut(&mut*self.as_raw_mut_ptr()) {
+                UserRef::from_mut_ptr(slice)
+            } else {
+                rtabort!("index out of range for user slice");
+            }
         }
     }
 }
@@ -540,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();