From 429855a8de0bfc6e4e3d97cabd664969b4353dc6 Mon Sep 17 00:00:00 2001 From: Charlie Tonneslan Date: Sat, 16 May 2026 19:52:51 -0400 Subject: [PATCH] nohup: create nohup.out with mode 0600 POSIX nohup creates the output file with permissions that block other users from reading it. We were leaving the mode at the process umask default, so on a typical system with umask 022 the file would land at 0644 and any other local user could read whatever the detached job logged. That's not great on multi-user hosts. Pass `.mode(0o600)` on the OpenOptions so newly-created `nohup.out` files start out as owner-only. Existing files keep their current permissions, which matches GNU. Closes #10021. Signed-off-by: Charlie Tonneslan --- src/uu/nohup/src/nohup.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/uu/nohup/src/nohup.rs b/src/uu/nohup/src/nohup.rs index 510f8c38213..25586c0c854 100644 --- a/src/uu/nohup/src/nohup.rs +++ b/src/uu/nohup/src/nohup.rs @@ -12,6 +12,7 @@ use rustix::stdio::{dup2_stderr, dup2_stdin, dup2_stdout, stdout}; use std::env; use std::fs::{File, OpenOptions}; use std::io::{Error, ErrorKind, IsTerminal}; +use std::os::unix::fs::OpenOptionsExt; use std::os::unix::process::CommandExt; use std::path::{Path, PathBuf}; use std::process; @@ -152,7 +153,15 @@ fn find_stdout() -> UResult { } fn try_open_nohup_file(path: &str) -> std::io::Result { - let file = OpenOptions::new().create(true).append(true).open(path)?; + // POSIX nohup creates the output file with mode 0600 so that other + // users on a shared host can't read whatever the detached job logs. + // Setting `.mode()` here only affects newly-created files; if the + // file already exists its permissions are left alone. + let file = OpenOptions::new() + .create(true) + .append(true) + .mode(0o600) + .open(path)?; show_error!( "{}",