diff --git a/ChangeLog b/ChangeLog index 2de42c4b5..f9496530c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,19 @@ openbsd-compat/openbsd-compat.h openbsd-compat/strptime.c] Add strptime to the compat library which helps on platforms like old IRIX. Based on work by djm, tested by Tom Christensen. + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2010/08/12 21:49:44 + [ssh.c] + close any extra file descriptors inherited from parent at start and + reopen stdin/stdout to /dev/null when forking for ControlPersist. + + prevents tools that fork and run a captive ssh for communication from + failing to exit when the ssh completes while they wait for these fds to + close. The inherited fds may persist arbitrarily long if a background + mux master has been started by ControlPersist. cvs and scp were effected + by this. + + "please commit" markus@ 20100812 - (tim) [regress/login-timeout.sh regress/reconfigure.sh regress/reexec.sh diff --git a/ssh.c b/ssh.c index ab37c205d..4419f7642 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.345 2010/08/04 05:42:47 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.346 2010/08/12 21:49:44 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -237,6 +237,12 @@ main(int ac, char **av) __progname = ssh_get_progname(av[0]); init_rng(); + /* + * Discard other fds that are hanging around. These can cause problem + * with backgrounded ssh processes started by ControlPersist. + */ + closefrom(STDERR_FILENO + 1); + /* * Save the original real uid. It will be needed later (uid-swapping * may clobber the real uid). @@ -898,6 +904,7 @@ static void control_persist_detach(void) { pid_t pid; + int devnull; debug("%s: backgrounding master process", __func__); @@ -924,6 +931,16 @@ control_persist_detach(void) /* muxclient() doesn't return on success. */ fatal("Failed to connect to new control master"); } + if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { + error("%s: open(\"/dev/null\"): %s", __func__, + strerror(errno)); + } else { + if (dup2(devnull, STDIN_FILENO) == -1 || + dup2(devnull, STDOUT_FILENO) == -1) + error("%s: dup2: %s", __func__, strerror(errno)); + if (devnull > STDERR_FILENO) + close(devnull); + } } /* Do fork() after authentication. Used by "ssh -f" */