1+ use core:: mem:: { self , MaybeUninit } ;
2+
13use axerrno:: { AxError , AxResult } ;
24use axhal:: uspace:: UserContext ;
35use bytemuck:: AnyBitPattern ;
4- use starry_vm:: VmPtr ;
6+ use starry_vm:: vm_read_slice ;
57
68use super :: clone:: { CloneArgs , CloneFlags } ;
79
@@ -66,7 +68,7 @@ impl TryFrom<Clone3Args> for CloneArgs {
6668 }
6769}
6870
69- pub fn sys_clone3 ( uctx : & UserContext , args : * const Clone3Args , size : usize ) -> AxResult < isize > {
71+ pub fn sys_clone3 ( uctx : & UserContext , args : * const u8 , size : usize ) -> AxResult < isize > {
7072 debug ! ( "sys_clone3 <= args: {args:p}, size: {size}" ) ;
7173
7274 if size < MIN_CLONE_ARGS_SIZE {
@@ -78,9 +80,14 @@ pub fn sys_clone3(uctx: &UserContext, args: *const Clone3Args, size: usize) -> A
7880 debug ! ( "sys_clone3: size {size} larger than expected, using known fields only" ) ;
7981 }
8082
81- let clone3_args = args. vm_read ( ) ?;
82-
83- debug ! ( "sys_clone3: args = {clone3_args:?}" ) ;
83+ let mut buffer = [ 0u8 ; core:: mem:: size_of :: < Clone3Args > ( ) ] ;
84+ // SAFETY: MaybeUninit<T> is compatible with T, and we're filling in the
85+ // buffer with bytes read from the user
86+ vm_read_slice ( args, unsafe {
87+ mem:: transmute :: < & mut [ u8 ] , & mut [ MaybeUninit < u8 > ] > ( & mut buffer[ ..size] )
88+ } ) ?;
89+ let clone3_args: Clone3Args =
90+ bytemuck:: try_pod_read_unaligned ( & buffer) . map_err ( |_| AxError :: InvalidInput ) ?;
8491
8592 let clone_args = CloneArgs :: try_from ( clone3_args) ?;
8693 clone_args. do_clone ( uctx)
0 commit comments