From 2ed207cb1fe7ae51ffc1c987ef1c7848f2b56358 Mon Sep 17 00:00:00 2001 From: =?utf8?q?P=C3=A1draig=20Brady?= Date: Tue, 9 Sep 2025 12:11:00 +0100 Subject: [PATCH] nohup: avoid FORTIFY runtime failure on Bionic libc The meaning of non-file permission umask bits is implementation defined. On Bionic libc, attempting to set them triggers a FORTIFY runtime check. $ nohup true FORTIFY: umask: called with invalid mask -601 Aborted nohup true * src/nohup.c: (main) Avoid setting non-permission bits in umask. Just clear the umask to ensure we create nohup.out with u+rw, as we restore the original umask before the exec(). * tests/misc/nohup.sh: Add a test case. * NEWS: Mention the bug fix. --- NEWS | 4 ++++ src/nohup.c | 2 +- tests/misc/nohup.sh | 20 ++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index 283d8046d5..392129dad2 100644 --- a/NEWS +++ b/NEWS @@ -47,6 +47,10 @@ GNU coreutils NEWS -*- outline -*- with multi-byte thousands grouping characters. [This bug was present in "the beginning".] + 'nohup' avoids implementation defined behavior setting umask, + avoiding a FORTIFY runtime failure on Bionic libc. + [This bug was present in "the beginning".] + 'od --strings' with '-N' now works correctly. Previously od might write a NUL byte after a heap buffer, or output invalid addresses. [These bugs were present in "the beginning".] diff --git a/src/nohup.c b/src/nohup.c index d58fcc53f0..6218986cb5 100644 --- a/src/nohup.c +++ b/src/nohup.c @@ -141,7 +141,7 @@ main (int argc, char **argv) char const *file = "nohup.out"; int flags = O_CREAT | O_WRONLY | O_APPEND; mode_t mode = S_IRUSR | S_IWUSR; - mode_t umask_value = umask (~mode); + mode_t umask_value = umask (0); out_fd = (redirecting_stdout ? fd_reopen (STDOUT_FILENO, file, flags, mode) : open (file, flags, mode)); diff --git a/tests/misc/nohup.sh b/tests/misc/nohup.sh index 917d2a3893..f49997f269 100755 --- a/tests/misc/nohup.sh +++ b/tests/misc/nohup.sh @@ -122,4 +122,24 @@ export POSIXLY_CORRECT=1 returns_ 127 nohup >/dev/null 2>&1 || fail=1 unset POSIXLY_CORRECT +# Make sure we create nohup.out with u+rw permissions +( + rm -f nohup.out + + # POSIX shells immediately exit the subshell on exec error. + # So check we can write to /dev/tty before the exec, which + # isn't possible if we've no controlling tty for example. + test -c /dev/tty && >/dev/tty || exit 0 + exec >/dev/tty + test -t 1 || exit 0 + + umask 600 # Ensure nohup undoes this + + nohup echo hi || fail=1 + test "$(stat -c %a nohup.out)" = 600 || fail=1 + + rm -f nohup.out + exit $fail +) || fail=1 + Exit $fail -- 2.47.3