@@ -6,7 +6,7 @@ use super::super::mem::{is_enclave_range, is_user_range};
6
6
use crate :: arch:: asm;
7
7
use crate :: cell:: UnsafeCell ;
8
8
use crate :: convert:: TryInto ;
9
- use crate :: mem:: { self , ManuallyDrop } ;
9
+ use crate :: mem:: { self , ManuallyDrop , MaybeUninit } ;
10
10
use crate :: ops:: { CoerceUnsized , Deref , DerefMut , Index , IndexMut } ;
11
11
use crate :: pin:: PinCoerceUnsized ;
12
12
use crate :: ptr:: { self , NonNull } ;
@@ -209,6 +209,45 @@ impl<T: ?Sized> NewUserRef<NonNull<T>> for NonNull<UserRef<T>> {
209
209
}
210
210
}
211
211
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
+
212
251
#[ unstable( feature = "sgx_platform" , issue = "56975" ) ]
213
252
impl < T : ?Sized > User < T >
214
253
where
@@ -544,12 +583,12 @@ where
544
583
/// # Panics
545
584
/// This function panics if the destination doesn't have the same size as
546
585
/// 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 ) {
548
587
unsafe {
549
588
assert_eq ! ( size_of_val( dest) , size_of_val( & * self . 0 . get( ) ) ) ;
550
589
copy_from_userspace (
551
590
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 ,
553
592
size_of_val ( dest) ,
554
593
) ;
555
594
}
@@ -639,25 +678,18 @@ where
639
678
unsafe { ( * self . 0 . get ( ) ) . len ( ) }
640
679
}
641
680
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 ( ) ] ) ;
652
685
// 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 ( ) ) } ;
655
687
}
656
688
657
689
/// Copies the value from user memory into a vector in enclave memory.
658
690
pub fn to_enclave ( & self ) -> Vec < T > {
659
691
let mut ret = Vec :: with_capacity ( self . len ( ) ) ;
660
- self . copy_to_enclave_vec ( & mut ret) ;
692
+ self . append_to_enclave_vec ( & mut ret) ;
661
693
ret
662
694
}
663
695
0 commit comments