about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThalia Archibald <thalia@archibald.dev>2025-02-26 11:51:28 -0800
committerThalia Archibald <thalia@archibald.dev>2025-03-11 20:16:31 -0700
commitc62aa0baa1a8228d5bfbb3e810db4c7ee77eb3a1 (patch)
treed9443d15e5d7e0d747b106380f7c623737759eac
parent8c7a94e4cdd9ad70550b19ca2bf6f16046d59506 (diff)
downloadrust-c62aa0baa1a8228d5bfbb3e810db4c7ee77eb3a1.tar.gz
rust-c62aa0baa1a8228d5bfbb3e810db4c7ee77eb3a1.zip
Fix `UserRef<[T]>::copy_to_enclave_vec`
It reinterprets uninitialized memory as initialized and does not drop
existing elements of the Vec. Fix that.

Additionally, make it more general by appending, instead of overwriting
existing elements, and rename it to `append_to_enclave_vec`. A caller
can simply call `.clear()` before, for the old behavior.
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs19
1 files changed, 6 insertions, 13 deletions
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
index 0132c1bd3f2..3fe6dee3d6f 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -678,25 +678,18 @@ where
         unsafe { (*self.0.get()).len() }
     }
 
-    /// Copies the value from user memory and place it into `dest`. Afterwards,
-    /// `dest` will contain exactly `self.len()` elements.
-    ///
-    /// # Panics
-    /// This function panics if the destination doesn't have the same size as
-    /// the source. This can happen for dynamically-sized types such as slices.
-    pub fn copy_to_enclave_vec(&self, dest: &mut Vec<T>) {
-        if let Some(missing) = self.len().checked_sub(dest.capacity()) {
-            dest.reserve(missing)
-        }
+    /// Copies the value from user memory and appends it to `dest`.
+    pub fn append_to_enclave_vec(&self, dest: &mut Vec<T>) {
+        dest.reserve(self.len());
+        self.copy_to_enclave(&mut dest.spare_capacity_mut()[..self.len()]);
         // SAFETY: We reserve enough space above.
-        unsafe { dest.set_len(self.len()) };
-        self.copy_to_enclave(&mut dest[..]);
+        unsafe { dest.set_len(dest.len() + self.len()) };
     }
 
     /// Copies the value from user memory into a vector in enclave memory.
     pub fn to_enclave(&self) -> Vec<T> {
         let mut ret = Vec::with_capacity(self.len());
-        self.copy_to_enclave_vec(&mut ret);
+        self.append_to_enclave_vec(&mut ret);
         ret
     }