diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs
index 99013efb495d0..326382d9038a8 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_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 @@ 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) {
- 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 @@ 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))
}
diff --git a/src/doc/unstable-book/src/library-features/asm.md b/src/doc/unstable-book/src/library-features/asm.md
index 84fc6dcc33979..c4e8c6e5eb86c 100644
--- a/src/doc/unstable-book/src/library-features/asm.md
+++ b/src/doc/unstable-book/src/library-features/asm.md
@@ -562,9 +562,12 @@ Here is the list of currently supported register classes:
| AArch64 | `vreg` | `v[0-31]` | `w` |
| AArch64 | `vreg_low16` | `v[0-15]` | `x` |
| AArch64 | `preg` | `p[0-15]`, `ffr` | Only clobbers |
-| ARM | `reg` | `r[0-12]`, `r14` | `r` |
-| ARM (Thumb) | `reg_thumb` | `r[0-r7]` | `l` |
+| ARM (ARM) | `reg` | `r[0-12]`, `r14` | `r` |
+| ARM (Thumb2) | `reg` | `r[0-12]`, `r14` | `r` |
+| ARM (Thumb1) | `reg` | `r[0-7]` | `r` |
| ARM (ARM) | `reg_thumb` | `r[0-r12]`, `r14` | `l` |
+| ARM (Thumb2) | `reg_thumb` | `r[0-7]` | `l` |
+| ARM (Thumb1) | `reg_thumb` | `r[0-7]` | `l` |
| ARM | `sreg` | `s[0-31]` | `t` |
| ARM | `sreg_low16` | `s[0-15]` | `x` |
| ARM | `dreg` | `d[0-31]` | `w` |
diff --git a/src/test/ui/command/command-pre-exec.rs b/src/test/ui/command/command-pre-exec.rs
index 10a8b19159e02..61914e2293070 100644
--- a/src/test/ui/command/command-pre-exec.rs
+++ b/src/test/ui/command/command-pre-exec.rs
@@ -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(())
})
diff --git a/src/test/ui/process/process-panic-after-fork.rs b/src/test/ui/process/process-panic-after-fork.rs
index ad749371beac0..1ccf6bb051c20 100644
--- a/src/test/ui/process/process-panic-after-fork.rs
+++ b/src/test/ui/process/process-panic-after-fork.rs
@@ -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 {
parent: A,
@@ -59,7 +44,7 @@ impl PidChecking {
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);
diff --git a/src/tools/miri b/src/tools/miri
index 9c18177cd36fe..a8b976eb350ac 160000
--- a/src/tools/miri
+++ b/src/tools/miri
@@ -1 +1 @@
-Subproject commit 9c18177cd36fe07a3c251234240a9c77a4e66785
+Subproject commit a8b976eb350acec83280a0cd1ca3ac99faff67bc