From fe05cf1fef8c4fd2d1fc0f4a1126fa74f9eda6bf Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Mon, 28 Mar 2022 16:46:30 +0100 Subject: [PATCH] moved clone extra args to stack --- src/clone.rs | 55 ++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/src/clone.rs b/src/clone.rs index 10167b6..fa41228 100644 --- a/src/clone.rs +++ b/src/clone.rs @@ -10,25 +10,17 @@ use nix::unistd::Pid; pub struct CloneArgs<'a> { pub flags: CloneFlags, - - pub pidfd: Option<&'a mut File>, - pidfd_int: RawFd, - - pub child_tid: Option<&'a mut Pid>, - child_tid_int: pid_t, - - pub parent_tid: Option<&'a mut Pid>, - parent_tid_int: pid_t, - + pub pidfd: Option<&'a mut Option>, + pub child_tid: Option<&'a mut Option>, + pub parent_tid: Option<&'a mut Option>, pub exit_signal: Option, - pub stack: Option<&'a mut [u8]>, pub set_tid: Option<&'a [Pid]>, pub cgroup: Option<&'a File>, } #[repr(C)] -struct CloneArgsInternal<'a> { +struct CloneArgsFfi<'a> { flags: u64, pidfd: u64, child_tid: u64, @@ -50,13 +42,9 @@ impl<'a: 'b, 'b: 'c, 'c> CloneArgs<'a> { flags, pidfd: None, - pidfd_int: 0, child_tid: None, - child_tid_int: 0, - parent_tid: None, - parent_tid_int: 0, exit_signal: None, @@ -66,23 +54,28 @@ impl<'a: 'b, 'b: 'c, 'c> CloneArgs<'a> { } } - fn process(&'b mut self) -> CloneArgsInternal<'c> { - CloneArgsInternal { + fn process( + &'b mut self, + pidfd: &mut RawFd, + child_tid: &mut pid_t, + parent_tid: &mut pid_t, + ) -> CloneArgsFfi<'c> { + CloneArgsFfi { flags: self.flags.bits() as u64, pidfd: self .pidfd .as_ref() - .map(|_| (self.pidfd_int) as *mut RawFd as u64) + .map(|_| pidfd as *mut RawFd as u64) .unwrap_or(0), child_tid: self .child_tid .as_ref() - .map(|_| self.child_tid_int as *mut pid_t as u64) + .map(|_| child_tid as *mut pid_t as u64) .unwrap_or(0), parent_tid: self .parent_tid .as_ref() - .map(|_| self.parent_tid_int as *mut pid_t as u64) + .map(|_| parent_tid as *mut pid_t as u64) .unwrap_or(0), exit_signal: self.exit_signal.map(|s| s as i32 as u64).unwrap_or(0), stack: self @@ -104,27 +97,33 @@ impl<'a: 'b, 'b: 'c, 'c> CloneArgs<'a> { } } - fn finalise(&mut self) { + unsafe fn finalise(&mut self, pidfd: RawFd, child_tid: pid_t, parent_tid: pid_t) { if let Some(r) = &mut self.pidfd { - **r = unsafe { File::from_raw_fd(self.pidfd_int) }; + **r = Some(File::from_raw_fd(pidfd)); } if let Some(r) = &mut self.child_tid { - **r = Pid::from_raw(self.child_tid_int); + **r = Some(Pid::from_raw(child_tid)); } if let Some(r) = &mut self.parent_tid { - **r = Pid::from_raw(self.parent_tid_int); + **r = Some(Pid::from_raw(parent_tid)); } } } pub fn clone3(mut args: CloneArgs) -> nix::Result { - let args_int: CloneArgsInternal = args.process(); + let mut pidfd: RawFd = 0; + let mut child_tid: pid_t = 0; + let mut parent_tid: pid_t = 0; - let result = unsafe { syscall(SYS_clone3, &args_int, std::mem::size_of_val(&args_int)) }; + let args_ffi: CloneArgsFfi = args.process(&mut pidfd, &mut child_tid, &mut parent_tid); + let result = unsafe { syscall(SYS_clone3, &args_ffi, std::mem::size_of_val(&args_ffi)) }; let out = Errno::result(result).map(|p| Pid::from_raw(p as i32))?; - args.finalise(); + // SAFETY: requested things have been filled by the kernel so are now valid for their type + unsafe { + args.finalise(pidfd, child_tid, parent_tid); + } Ok(out) }