Hi,
starting with v4.21, stunnel does not disconnect from the terminal anymore. This can cause problems, if the caller does not redirect stdout/stderr to /dev/null. This did not happen with v4.20.
The problem disappears, when I use he "--disable-libwrap" configure switch when compiling stunnel.
I am running debian testing on i386 with the stunnel4 package 4.22-2.
How to reproduce:
1) stunnel config file: setuid = lars pid = /tmp/stunnel.pid [server] connect = 8080 accept = 443 cert = /some/file
2) command line: cat stunnel.conf | stunnel4 -fd 0
3) process list: erker:~/ttt/stunnel/testing/stunnel-4.26# ps -ef| grep stun lars 29599 1 0 13:47 pts/1 00:00:00 src/stunnel -fd 0 lars 29600 1 0 13:47 pts/1 00:00:00 src/stunnel -fd 0 lars 29601 1 0 13:47 pts/1 00:00:00 src/stunnel -fd 0 lars 29602 1 0 13:47 pts/1 00:00:00 src/stunnel -fd 0 lars 29603 1 0 13:47 pts/1 00:00:00 src/stunnel -fd 0 lars 29604 1 0 13:47 ? 00:00:00 src/stunnel -fd 0
4) FDs of spawned processes: erker:~/ttt/stunnel/testing/stunnel-4.26# ls -l /proc/29599/fd lrwx------ 1 root root 64 Jan 10 13:50 1 -> /dev/pts/1 lrwx------ 1 root root 64 Jan 10 13:47 2 -> /dev/pts/1 lrwx------ 1 root root 64 Jan 10 13:50 3 -> socket:[903037]
Is this the expected behaviour? I use stunnel in one of my projects (http://cryptonas.org) and it started to hang with v4.22. After redirecting stdout/stderr to /dev/null, the program works again. I assume, that stunnel should take care for stdout/stderr on its own, when started in daemon mode, right?
thanks for your great work! Lars
Hi,
starting with v4.21, stunnel does not disconnect from the terminal anymore. This can cause problems, if the caller does not redirect stdout/stderr to /dev/null. This did not happen with v4.20.
does anybody have any comments on this?
Otherwise I would like to file a bug report for it, to prevent it from getting lost. Additionally this would give a reference for the related debian bug report[1]. But I could not find the link to the issue tracker on http://stunnel.org. Would somebody please point me to the right place?
thanks! Lars
On Wed, Jan 21, 2009 at 02:20:16AM +0100, Lars Kruse wrote:
Hi,
starting with v4.21, stunnel does not disconnect from the terminal anymore. This can cause problems, if the caller does not redirect stdout/stderr to /dev/null. This did not happen with v4.20.
does anybody have any comments on this?
The following patch fixes the issue, but I think it's too heavy handed, daemonizing each libwrap process by itself to get it detached and thus putting each in its own process group. It confirms the diagnostic that this is caused by those processes remaining attached to the terminal, at least.
---------------------------------------------------------------------- diff --git a/src/libwrap.c b/src/libwrap.c index b71fd28..7924eb3 100644 --- a/src/libwrap.c +++ b/src/libwrap.c @@ -80,6 +80,7 @@ void libwrap_init(int num) { die(1); case 0: /* child */ drop_privileges(); /* libwrap processes are not chrooted */ + daemonize(); /* detach from terminal */ /* FIXME: other file descriptors are not closed */ close(ipc_socket[2*i]); /* server-side socket */ for(j=0; j<i; ++j) /* previously created client-side sockets */ diff --git a/src/prototypes.h b/src/prototypes.h index e0efabd..fad8c59 100644 --- a/src/prototypes.h +++ b/src/prototypes.h @@ -76,6 +76,9 @@ void main_execute(void); #if !defined (USE_WIN32) && !defined (__vms) && !defined(USE_OS2) void drop_privileges(void); #endif +#if !defined (USE_WIN32) && !defined (__vms) +void daemonize(void); +#endif void stunnel_info(int); void die(int);
diff --git a/src/stunnel.c b/src/stunnel.c index 9d18782..86df5ab 100644 --- a/src/stunnel.c +++ b/src/stunnel.c @@ -44,7 +44,6 @@ static void accept_connection(LOCAL_OPTIONS *); static void get_limits(void); /* setup global max_clients and max_fds */ #if !defined (USE_WIN32) && !defined (__vms) static void change_root(void); -static void daemonize(void); static void create_pid(void); static void delete_pid(void); #endif @@ -347,7 +346,7 @@ void drop_privileges(void) { } }
-static void daemonize(void) { /* go to background */ +void daemonize(void) { /* go to background */ #if defined(HAVE_DAEMON) && !defined(__BEOS__) if(daemon(0, 0)==-1) { ioerror("daemon"); ----------------------------------------------------------------------
On Wed, Jan 21, 2009 at 02:20:16AM +0100, Lars Kruse wrote:
Hi,
starting with v4.21, stunnel does not disconnect from the terminal anymore. This can cause problems, if the caller does not redirect stdout/stderr to /dev/null. This did not happen with v4.20.
does anybody have any comments on this?
I've come up with a better looking patch. It appears that, on Linux at least, simply closing std{in,out,err} in the libwrap helper processes is enough to fix this.
I'd be glad if someone could check the behaviour in other OSs.
---------------------------------------------------------------------- --- stunnel4.orig/src/libwrap.c +++ stunnel4/src/libwrap.c @@ -81,6 +81,12 @@ case 0: /* child */ drop_privileges(); /* libwrap processes are not chrooted */ /* FIXME: other file descriptors are not closed */ + if (!options.option.foreground) { + /* Detach from terminal. */ + close(0); + close(1); + close(2); + } close(ipc_socket[2*i]); /* server-side socket */ for(j=0; j<i; ++j) /* previously created client-side sockets */ close(ipc_socket[2*j+1]); ----------------------------------------------------------------------
Rodrigo Gallardo rodrigo@debian.org wrote:
if (!options.option.foreground) {
/* Detach from terminal. */
close(0);
close(1);
close(2);
}
Thank you. The functionality of this patch is implemented upstream. The next version of stunnel is scheduled to be released this week.
BTW: Checking for options.option.foreground is not required, as the libwrap helper process is not supposed to interact with stdin/stdout/stderr anyway.
Best regards, Mike
Very good news. Thanks.
On Mon, Mar 02, 2009 at 01:35:54PM +0100, Michal Trojnara wrote:
Thank you. The functionality of this patch is implemented upstream. The next version of stunnel is scheduled to be released this week.
Neat.
BTW: Checking for options.option.foreground is not required, as the libwrap helper process is not supposed to interact with stdin/stdout/stderr anyway.
Not even for logging within read_fd?