about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJethro Beekman <jethro@fortanix.com>2025-02-28 13:33:05 +0100
committerThalia Archibald <thalia@archibald.dev>2025-03-10 00:45:19 -0700
commitb52666868ffd88a52bf1471f567505ab950da383 (patch)
tree71fd8fb450629f67021e5e4ff81160ff42bdecd4
parent2c6a12ec44d0426c8939123c2f2cf27d2217de13 (diff)
downloadrust-b52666868ffd88a52bf1471f567505ab950da383.tar.gz
rust-b52666868ffd88a52bf1471f567505ab950da383.zip
Copy from userspace to MaybeUninit
Co-authored-by: Thalia Archibald <thalia@archibald.dev>
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs45
1 files changed, 42 insertions, 3 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 301e3299c05..0132c1bd3f2 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range};
 use crate::arch::asm;
 use crate::cell::UnsafeCell;
 use crate::convert::TryInto;
-use crate::mem::{self, ManuallyDrop};
+use crate::mem::{self, ManuallyDrop, MaybeUninit};
 use crate::ops::{CoerceUnsized, Deref, DerefMut, Index, IndexMut};
 use crate::pin::PinCoerceUnsized;
 use crate::ptr::{self, NonNull};
@@ -209,6 +209,45 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
     }
 }
 
+/// A type which can a destination for safely copying from userspace.
+///
+/// # Safety
+///
+/// Requires that `T` and `Self` have identical layouts.
+#[unstable(feature = "sgx_platform", issue = "56975")]
+pub unsafe trait UserSafeCopyDestination<T: ?Sized> {
+    /// Returns a pointer for writing to the value.
+    fn as_mut_ptr(&mut self) -> *mut T;
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<T> for T {
+    fn as_mut_ptr(&mut self) -> *mut T {
+        self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<[T]> for [T] {
+    fn as_mut_ptr(&mut self) -> *mut [T] {
+        self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<T> for MaybeUninit<T> {
+    fn as_mut_ptr(&mut self) -> *mut T {
+        self as *mut Self as _
+    }
+}
+
+#[unstable(feature = "sgx_platform", issue = "56975")]
+unsafe impl<T> UserSafeCopyDestination<[T]> for [MaybeUninit<T>] {
+    fn as_mut_ptr(&mut self) -> *mut [T] {
+        self as *mut Self as _
+    }
+}
+
 #[unstable(feature = "sgx_platform", issue = "56975")]
 impl<T: ?Sized> User<T>
 where
@@ -544,12 +583,12 @@ where
     /// # 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(&self, dest: &mut T) {
+    pub fn copy_to_enclave<U: ?Sized + UserSafeCopyDestination<T>>(&self, dest: &mut U) {
         unsafe {
             assert_eq!(size_of_val(dest), size_of_val(&*self.0.get()));
             copy_from_userspace(
                 self.0.get() as *const T as *const u8,
-                dest as *mut T as *mut u8,
+                dest.as_mut_ptr() as *mut u8,
                 size_of_val(dest),
             );
         }