]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
upstream commit
authordtucker@openbsd.org <dtucker@openbsd.org>
Wed, 30 Nov 2016 00:28:31 +0000 (00:28 +0000)
committerDamien Miller <djm@mindrot.org>
Wed, 30 Nov 2016 08:44:01 +0000 (19:44 +1100)
On startup, check to see if sshd is already daemonized
and if so, skip the call to daemon() and do not rewrite the PidFile.  This
means that when sshd re-execs itself on SIGHUP the process ID will no longer
change.  Should address bz#2641.  ok djm@ markus@.

Upstream-ID: 5ea0355580056fb3b25c1fd6364307d9638a37b9

misc.c
misc.h
sshd.c

diff --git a/misc.c b/misc.c
index 07d4179e479d34928afc9e9cbd8c02f5baef89a7..65c9222aa8b0ce3be5e6a37af77b7c6d03696ce8 100644 (file)
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.c,v 1.106 2016/10/23 22:04:05 dtucker Exp $ */
+/* $OpenBSD: misc.c,v 1.107 2016/11/30 00:28:31 dtucker Exp $ */
 /*
  * Copyright (c) 2000 Markus Friedl.  All rights reserved.
  * Copyright (c) 2005,2006 Damien Miller.  All rights reserved.
@@ -1251,3 +1251,21 @@ bind_permitted(int port, uid_t uid)
                return 0;
        return 1;
 }
+
+/* returns 1 if process is already daemonized, 0 otherwise */
+int
+daemonized(void)
+{
+       int fd;
+
+       if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
+               close(fd);
+               return 0;       /* have controlling terminal */
+       }
+       if (getppid() != 1)
+               return 0;       /* parent is not init */
+       if (getsid(0) != getpid())
+               return 0;       /* not session leader */
+       debug3("already daemonized");
+       return 1;
+}
diff --git a/misc.h b/misc.h
index 3578e8ef539935730f9f86f09c84ae532a01c9d0..c242f9011f592f694522effa849749e46f0f1af1 100644 (file)
--- a/misc.h
+++ b/misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: misc.h,v 1.60 2016/10/23 22:04:05 dtucker Exp $ */
+/* $OpenBSD: misc.h,v 1.61 2016/11/30 00:28:31 dtucker Exp $ */
 
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -31,6 +31,7 @@ struct Forward {
 
 int forward_equals(const struct Forward *, const struct Forward *);
 int bind_permitted(int, uid_t);
+int daemonized(void);
 
 /* Common server and client forwarding options. */
 struct ForwardOptions {
diff --git a/sshd.c b/sshd.c
index ce4a493ef88c3d18eb1e04326a0ee2dec87517ce..fafcd3400b889e455f3577a8322465ff84835fdf 100644 (file)
--- a/sshd.c
+++ b/sshd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sshd.c,v 1.477 2016/11/29 03:54:50 dtucker Exp $ */
+/* $OpenBSD: sshd.c,v 1.478 2016/11/30 00:28:31 dtucker Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1343,7 +1343,7 @@ main(int ac, char **av)
        struct ssh *ssh = NULL;
        extern char *optarg;
        extern int optind;
-       int r, opt, i, j, on = 1;
+       int r, opt, i, j, on = 1, already_daemon;
        int sock_in = -1, sock_out = -1, newsock = -1;
        const char *remote_ip;
        int remote_port;
@@ -1802,11 +1802,12 @@ main(int ac, char **av)
        log_init(__progname, options.log_level, options.log_facility, log_stderr);
 
        /*
-        * If not in debugging mode, and not started from inetd, disconnect
-        * from the controlling terminal, and fork.  The original process
-        * exits.
+        * If not in debugging mode, not started from inetd and not already
+        * daemonized (eg re-exec via SIGHUP), disconnect from the controlling
+        * terminal, and fork.  The original process exits.
         */
-       if (!(debug_flag || inetd_flag || no_daemon_flag)) {
+       already_daemon = daemonized();
+       if (!(debug_flag || inetd_flag || no_daemon_flag || already_daemon)) {
 
                if (daemon(0, 0) < 0)
                        fatal("daemon() failed: %.200s", strerror(errno));
@@ -1840,7 +1841,7 @@ main(int ac, char **av)
                 * Write out the pid file after the sigterm handler
                 * is setup and the listen sockets are bound
                 */
-               if (options.pid_file != NULL && !debug_flag) {
+               if (options.pid_file != NULL && !debug_flag && !already_daemon) {
                        FILE *f = fopen(options.pid_file, "w");
 
                        if (f == NULL) {