@@ -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 }
@@ -639,25 +678,18 @@ where
639678 unsafe { ( * self . 0 . get ( ) ) . len ( ) }
640679 }
641680
642- /// Copies the value from user memory and place it into `dest`. Afterwards,
643- /// `dest` will contain exactly `self.len()` elements.
644- ///
645- /// # Panics
646- /// This function panics if the destination doesn't have the same size as
647- /// the source. This can happen for dynamically-sized types such as slices.
648- pub fn copy_to_enclave_vec ( & self , dest : & mut Vec < T > ) {
649- if let Some ( missing) = self . len ( ) . checked_sub ( dest. capacity ( ) ) {
650- dest. reserve ( missing)
651- }
681+ /// Copies the value from user memory and appends it to `dest`.
682+ pub fn append_to_enclave_vec ( & self , dest : & mut Vec < T > ) {
683+ dest. reserve ( self . len ( ) ) ;
684+ self . copy_to_enclave ( & mut dest. spare_capacity_mut ( ) [ ..self . len ( ) ] ) ;
652685 // SAFETY: We reserve enough space above.
653- unsafe { dest. set_len ( self . len ( ) ) } ;
654- self . copy_to_enclave ( & mut dest[ ..] ) ;
686+ unsafe { dest. set_len ( dest. len ( ) + self . len ( ) ) } ;
655687 }
656688
657689 /// Copies the value from user memory into a vector in enclave memory.
658690 pub fn to_enclave ( & self ) -> Vec < T > {
659691 let mut ret = Vec :: with_capacity ( self . len ( ) ) ;
660- self . copy_to_enclave_vec ( & mut ret) ;
692+ self . append_to_enclave_vec ( & mut ret) ;
661693 ret
662694 }
663695
0 commit comments