Rollup merge of #89930 - cuviper:avoid-clone3, r=joshtriplett

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`.

This is a re-application of beta #89924, now that we're aware that we need
more than just a temporary release fix. I also reverted 12fbabd27f, as
that was just fallout from using `clone3` instead of `fork`.

r? `@Mark-Simulacrum`
cc `@joshtriplett`
This commit is contained in:
Matthias Krüger 2021-11-10 23:04:25 +01:00 committed by GitHub
commit a09115f3b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 17 additions and 44 deletions

View file

@ -8,6 +8,8 @@
// ignore-sgx no processes
#![feature(process_exec, rustc_private)]
extern crate libc;
use std::env;
use std::io::Error;
use std::os::unix::process::CommandExt;
@ -15,23 +17,6 @@ use std::process::Command;
use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
#[cfg(not(target_os = "linux"))]
fn getpid() -> u32 {
use std::process;
process::id()
}
/// We need to directly use the getpid syscall instead of using `process::id()`
/// because the libc wrapper might return incorrect values after a process was
/// forked.
#[cfg(target_os = "linux")]
fn getpid() -> u32 {
extern crate libc;
unsafe {
libc::syscall(libc::SYS_getpid) as _
}
}
fn main() {
if let Some(arg) = env::args().nth(1) {
match &arg[..] {
@ -83,12 +68,14 @@ fn main() {
};
assert_eq!(output.raw_os_error(), Some(102));
let pid = getpid();
let pid = unsafe { libc::getpid() };
assert!(pid >= 0);
let output = unsafe {
Command::new(&me)
.arg("empty")
.pre_exec(move || {
let child = getpid();
let child = libc::getpid();
assert!(child >= 0);
assert!(pid != child);
Ok(())
})

View file

@ -23,21 +23,6 @@ use std::sync::atomic::{AtomicU32, Ordering};
use libc::c_int;
#[cfg(not(target_os = "linux"))]
fn getpid() -> u32 {
process::id()
}
/// We need to directly use the getpid syscall instead of using `process::id()`
/// because the libc wrapper might return incorrect values after a process was
/// forked.
#[cfg(target_os = "linux")]
fn getpid() -> u32 {
unsafe {
libc::syscall(libc::SYS_getpid) as _
}
}
/// This stunt allocator allows us to spot heap allocations in the child.
struct PidChecking<A> {
parent: A,
@ -59,7 +44,7 @@ impl<A> PidChecking<A> {
fn check(&self) {
let require_pid = self.require_pid.load(Ordering::Acquire);
if require_pid != 0 {
let actual_pid = getpid();
let actual_pid = process::id();
if require_pid != actual_pid {
unsafe {
libc::raise(libc::SIGUSR1);