Skip to content

Commit 7df8c08

Browse files
authored
Merge pull request #419 from memorysafety/fork-is-safe-in-linux
Conditionally mark `fork` as safe in linux
2 parents e22cd3f + ced3f42 commit 7df8c08

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/sudo-exec/src/lib.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,7 @@ pub fn run_command(ctx: Context, env: Environment) -> io::Result<(ExitReason, im
7070

7171
let (pty_leader, pty_follower) = openpty()?;
7272
let (rx, tx) = pipe()?;
73-
// SAFETY: we don't call any function that is not `async-signal-safe` inside this `fork` as all
74-
// the signal handling is done by `signal_hook` which protects us from it.
75-
#[allow(unsafe_code)]
76-
let monitor_pid = unsafe { fork() }?;
73+
let monitor_pid = fork()?;
7774
// Monitor logic. Based on `exec_monitor`.
7875
if monitor_pid == 0 {
7976
match monitor::MonitorRelay::new(command, pty_follower, tx)?.run()? {}

lib/sudo-system/src/lib.rs

+15
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,21 @@ pub fn pipe() -> io::Result<(OwnedFd, OwnedFd)> {
4444
Ok(unsafe { (OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])) })
4545
}
4646

47+
#[cfg(target_os = "linux")]
48+
/// Create a new process.
49+
pub fn fork() -> io::Result<ProcessId> {
50+
// SAFETY: `fork` is implemented using `clone` in linux so we don't need to worry about signal
51+
// safety.
52+
cerr(unsafe { libc::fork() })
53+
}
54+
55+
#[cfg(not(target_os = "linux"))]
56+
/// Create a new process.
57+
///
58+
/// # Safety
59+
///
60+
/// In a multithreaded program, only async-signal-safe functions are guaranteed to work in the
61+
/// child process until a call to `execve` or a similar function is done.
4762
pub unsafe fn fork() -> io::Result<ProcessId> {
4863
cerr(unsafe { libc::fork() })
4964
}

0 commit comments

Comments
 (0)