@@ -166,21 +166,22 @@ impl Command {
166166 fn clone3( cl_args: * mut clone_args, len: libc:: size_t) -> libc:: c_long
167167 }
168168
169+ // Bypassing libc for `clone3` can make further libc calls unsafe,
170+ // so we use it sparingly for now. See #89522 for details.
171+ // Some tools (e.g. sandboxing tools) may also expect `fork`
172+ // rather than `clone3`.
173+ let want_clone3_pidfd = self . get_create_pidfd ( ) ;
174+
169175 // If we fail to create a pidfd for any reason, this will
170176 // stay as -1, which indicates an error.
171177 let mut pidfd: pid_t = -1 ;
172178
173179 // Attempt to use the `clone3` syscall, which supports more arguments
174180 // (in particular, the ability to create a pidfd). If this fails,
175181 // we will fall through this block to a call to `fork()`
176- if HAS_CLONE3 . load ( Ordering :: Relaxed ) {
177- let mut flags = 0 ;
178- if self . get_create_pidfd ( ) {
179- flags |= CLONE_PIDFD ;
180- }
181-
182+ if want_clone3_pidfd && HAS_CLONE3 . load ( Ordering :: Relaxed ) {
182183 let mut args = clone_args {
183- flags,
184+ flags : CLONE_PIDFD ,
184185 pidfd : & mut pidfd as * mut pid_t as u64 ,
185186 child_tid : 0 ,
186187 parent_tid : 0 ,
@@ -212,8 +213,8 @@ impl Command {
212213 }
213214 }
214215
215- // If we get here, the 'clone3' syscall does not exist
216- // or we do not have permission to call it
216+ // Generally, we just call `fork`. If we get here after wanting `clone3`,
217+ // then the syscall does not exist or we do not have permission to call it.
217218 cvt ( libc:: fork ( ) ) . map ( |res| ( res, pidfd) )
218219 }
219220
0 commit comments