@@ -166,21 +166,22 @@ impl Command {
166
166
fn clone3( cl_args: * mut clone_args, len: libc:: size_t) -> libc:: c_long
167
167
}
168
168
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
+
169
175
// If we fail to create a pidfd for any reason, this will
170
176
// stay as -1, which indicates an error.
171
177
let mut pidfd: pid_t = -1 ;
172
178
173
179
// Attempt to use the `clone3` syscall, which supports more arguments
174
180
// (in particular, the ability to create a pidfd). If this fails,
175
181
// 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 ) {
182
183
let mut args = clone_args {
183
- flags,
184
+ flags : CLONE_PIDFD ,
184
185
pidfd : & mut pidfd as * mut pid_t as u64 ,
185
186
child_tid : 0 ,
186
187
parent_tid : 0 ,
@@ -212,8 +213,8 @@ impl Command {
212
213
}
213
214
}
214
215
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.
217
218
cvt ( libc:: fork ( ) ) . map ( |res| ( res, pidfd) )
218
219
}
219
220
0 commit comments