summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorPaulo Alcantara <paulo@paulo.ac>2018-08-17 11:30:16 -0300
committerStefan Metzmacher <metze@samba.org>2018-09-05 13:31:39 +0200
commitb53eb6f62f83126c28fc8b7d55831f74a589a158 (patch)
treea0864f63c19ad2346ba84080b417535116a6c90f /lib
parent1b01025bf8c86dd67f36994733f0866eecffb3e1 (diff)
downloadsamba-b53eb6f62f83126c28fc8b7d55831f74a589a158.tar.gz
s3: util: Do not take over stderr when there is no log file
In case we don't have either a /var/log/samba directory, or pass a non-existent log directory through '-l' option, all commands that are daemonized with '-D' option hang when executed within a subshell. An example on how to trigger that: # rm -r /var/log/samba # s=$(nmbd -D -s /etc/samba/smb.conf -l /foo123) (never returns) So, when the above command is executed within a subshell the following happens: (a) Parent shell creates a pipe, sets write side of it to fd 1 (stdout), call read() on read-side fd, forks off a new child process and then executes nmbd in it. (b) nmbd sets up initial logging to go through fd 1 (stdout) by calling setup_logging(..., DEBUG_DEFAULT_STDOUT). 'state.fd' is now set to 1. (c) reopen_logs() is called by the first time which then calls reopen_logs_internal() (d) in reopen_logs_internal(), it attempts to create log.nmbd file in /foo123 directory and fails because directory doesn't exist. (e) Regardless whether the log file was created or not, it calls dup2(state.fd, 2) which dups fd 1 into fd 2. (f) At some point, fd 0 and 1 are closed and set to /dev/null The problem with that is because parent shell in (a) is still blocked in read() call and the new write side of the pipe is now fd 2 -- after dup2() in (e) -- and remains unclosed. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13578 Signed-off-by: Paulo Alcantara <palcantara@suse.de> Reviewed-by: Jim McDonough <jmcd@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Sat Aug 18 01:32:25 CEST 2018 on sn-devel-144 (cherry picked from commit 41aa55f49233ea7682cf14e5a7062617274434ce)
Diffstat (limited to 'lib')
-rw-r--r--lib/util/debug.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/lib/util/debug.c b/lib/util/debug.c
index b58303e8c82..022e37b36c7 100644
--- a/lib/util/debug.c
+++ b/lib/util/debug.c
@@ -1069,8 +1069,11 @@ bool reopen_logs_internal(void)
force_check_log_size();
(void)umask(oldumask);
- /* Take over stderr to catch output into logs */
- if (state.fd > 0) {
+ /*
+ * If log file was opened or created successfully, take over stderr to
+ * catch output into logs.
+ */
+ if (new_fd != -1) {
if (dup2(state.fd, 2) == -1) {
/* Close stderr too, if dup2 can't point it -
at the logfile. There really isn't much