Skip to content

Commit

Permalink
Rollup merge of #105598 - RalfJung:more-comments, r=the8472
Browse files Browse the repository at this point in the history
explain mem::forget(env_lock) in fork/exec

I stumbled upon this while doing triage for #64718.
  • Loading branch information
matthiaskrgr authored Dec 14, 2022
2 parents ba71a63 + 3465d5f commit 6d3a93c
Showing 1 changed file with 4 additions and 3 deletions.
7 changes: 4 additions & 3 deletions library/std/src/sys/unix/process/process_unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,15 @@ impl Command {
//
// Note that as soon as we're done with the fork there's no need to hold
// a lock any more because the parent won't do anything and the child is
// in its own process. Thus the parent drops the lock guard while the child
// forgets it to avoid unlocking it on a new thread, which would be invalid.
// in its own process. Thus the parent drops the lock guard immediately.
// The child calls `mem::forget` to leak the lock, which is crucial because
// releasing a lock is not async-signal-safe.
let env_lock = sys::os::env_read_lock();
let (pid, pidfd) = unsafe { self.do_fork()? };

if pid == 0 {
crate::panic::always_abort();
mem::forget(env_lock);
mem::forget(env_lock); // avoid non-async-signal-safe unlocking
drop(input);
let Err(err) = unsafe { self.do_exec(theirs, envp.as_ref()) };
let errno = err.raw_os_error().unwrap_or(libc::EINVAL) as u32;
Expand Down

0 comments on commit 6d3a93c

Please sign in to comment.