@@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range};
66use crate :: arch:: asm;
77use crate :: cell:: UnsafeCell ;
88use crate :: convert:: TryInto ;
9- use crate :: mem:: { self , ManuallyDrop } ;
9+ use crate :: mem:: { self , ManuallyDrop , MaybeUninit } ;
1010use crate :: ops:: { CoerceUnsized , Deref , DerefMut , Index , IndexMut } ;
1111use crate :: pin:: PinCoerceUnsized ;
1212use crate :: ptr:: { self , NonNull } ;
@@ -209,6 +209,45 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
209209 }
210210}
211211
212+ /// A type which can a destination for safely copying from userspace.
213+ ///
214+ /// # Safety
215+ ///
216+ /// Requires that `T` and `Self` have identical layouts.
217+ #[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
218+ pub unsafe trait UserSafeCopyDestination < T : ?Sized > {
219+ /// Returns a pointer for writing to the value.
220+ fn as_mut_ptr ( & mut self ) -> * mut T ;
221+ }
222+
223+ #[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
224+ unsafe impl < T > UserSafeCopyDestination < T > for T {
225+ fn as_mut_ptr ( & mut self ) -> * mut T {
226+ self as _
227+ }
228+ }
229+
230+ #[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
231+ unsafe impl < T > UserSafeCopyDestination < [ T ] > for [ T ] {
232+ fn as_mut_ptr ( & mut self ) -> * mut [ T ] {
233+ self as _
234+ }
235+ }
236+
237+ #[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
238+ unsafe impl < T > UserSafeCopyDestination < T > for MaybeUninit < T > {
239+ fn as_mut_ptr ( & mut self ) -> * mut T {
240+ self as * mut Self as _
241+ }
242+ }
243+
244+ #[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
245+ unsafe impl < T > UserSafeCopyDestination < [ T ] > for [ MaybeUninit < T > ] {
246+ fn as_mut_ptr ( & mut self ) -> * mut [ T ] {
247+ self as * mut Self as _
248+ }
249+ }
250+
212251#[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
213252impl < T : ?Sized > User < T >
214253where
@@ -544,12 +583,12 @@ where
544583 /// # Panics
545584 /// This function panics if the destination doesn't have the same size as
546585 /// the source. This can happen for dynamically-sized types such as slices.
547- pub fn copy_to_enclave ( & self , dest : & mut T ) {
586+ pub fn copy_to_enclave < U : ? Sized + UserSafeCopyDestination < T > > ( & self , dest : & mut U ) {
548587 unsafe {
549588 assert_eq ! ( size_of_val( dest) , size_of_val( & * self . 0 . get( ) ) ) ;
550589 copy_from_userspace (
551590 self . 0 . get ( ) as * const T as * const u8 ,
552- dest as * mut T as * mut u8 ,
591+ dest. as_mut_ptr ( ) as * mut u8 ,
553592 size_of_val ( dest) ,
554593 ) ;
555594 }
0 commit comments