summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-16 15:27:00 +0000
committerbors <bors@rust-lang.org>2021-10-16 15:27:00 +0000
commit7eda9439636b4b56c74349b7309aff8109702e86 (patch)
treef9893001af4242c9fa29eeb22998f9703b0c82a4
parent58268ff091703ace98c3c2a8c5f2fb2c3aecace2 (diff)
parent74ef5300ef72fd21d42fea39c02f49c302fbb242 (diff)
downloadrust-7eda9439636b4b56c74349b7309aff8109702e86.tar.gz
rust-7eda9439636b4b56c74349b7309aff8109702e86.zip
Auto merge of #89924 - cuviper:beta-clone3, r=Mark-Simulacrum
Only use `clone3` when needed for pidfd

In #89522 we learned that `clone3` is interacting poorly with Gentoo's
`sandbox` tool. We only need that for the unstable pidfd extensions, so
otherwise avoid that and use a normal `fork`.

r? `@Mark-Simulacrum`
-rw-r--r--library/std/src/sys/unix/process/process_unix.rs12
1 files changed, 9 insertions, 3 deletions
diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 12edf04a4e2..11d23a32890 100644
--- a/library/std/src/sys/unix/process/process_unix.rs
+++ b/library/std/src/sys/unix/process/process_unix.rs
@@ -166,6 +166,12 @@ impl Command {
             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 = 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,7 +179,7 @@ impl Command {
         // 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) {
+        if want_clone3 && HAS_CLONE3.load(Ordering::Relaxed) {
             let mut flags = 0;
             if self.get_create_pidfd() {
                 flags |= CLONE_PIDFD;
@@ -212,8 +218,8 @@ impl Command {
             }
         }
 
-        // 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))
     }