]> git.lizzy.rs Git - rust.git/blobdiff - library/std/src/sys/unix/process/process_unix.rs
Rollup merge of #90704 - ijackson:exitstatus-comments, r=joshtriplett
[rust.git] / library / std / src / sys / unix / process / process_unix.rs
index 7e674910f8e6162d9b00020bba682e98c071e4b7..3bf1493f3b8cbd6860cadddd0f7f44789b47d95d 100644 (file)
@@ -166,6 +166,12 @@ struct clone_args {
             fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
         }
 
+        // Bypassing libc for `clone3` can make further libc calls unsafe,
+        // so we use it sparingly for now. See #89522 for details.
+        // Some tools (e.g. sandboxing tools) may also expect `fork`
+        // rather than `clone3`.
+        let want_clone3_pidfd = self.get_create_pidfd();
+
         // If we fail to create a pidfd for any reason, this will
         // stay as -1, which indicates an error.
         let mut pidfd: pid_t = -1;
@@ -173,14 +179,9 @@ fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
         // Attempt to use the `clone3` syscall, which supports more arguments
         // (in particular, the ability to create a pidfd). If this fails,
         // we will fall through this block to a call to `fork()`
-        if HAS_CLONE3.load(Ordering::Relaxed) {
-            let mut flags = 0;
-            if self.get_create_pidfd() {
-                flags |= CLONE_PIDFD;
-            }
-
+        if want_clone3_pidfd && HAS_CLONE3.load(Ordering::Relaxed) {
             let mut args = clone_args {
-                flags,
+                flags: CLONE_PIDFD,
                 pidfd: &mut pidfd as *mut pid_t as u64,
                 child_tid: 0,
                 parent_tid: 0,
@@ -212,8 +213,8 @@ fn clone3(cl_args: *mut clone_args, len: libc::size_t) -> libc::c_long
             }
         }
 
-        // If we get here, the 'clone3' syscall does not exist
-        // or we do not have permission to call it
+        // Generally, we just call `fork`. If we get here after wanting `clone3`,
+        // then the syscall does not exist or we do not have permission to call it.
         cvt(libc::fork()).map(|res| (res, pidfd))
     }