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.
This commit is contained in:
Thalia Archibald 2025-02-26 11:51:28 -08:00
parent 8c7a94e4cd
commit c62aa0baa1

View file

@ -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
}