summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordtucker@openbsd.org <dtucker@openbsd.org>2016-11-30 00:28:31 +0000
committerDamien Miller <djm@mindrot.org>2016-11-30 19:44:01 +1100
commit7fc4766ac78abae81ee75b22b7550720bfa28a33 (patch)
tree36cc862d4d493587327dc91f89cf96b22e8230ee
parentc9f880c195c65f1dddcbc4ce9d6bfea7747debcc (diff)
upstream commit
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
-rw-r--r--misc.c20
-rw-r--r--misc.h3
-rw-r--r--sshd.c15
3 files changed, 29 insertions, 9 deletions
diff --git a/misc.c b/misc.c
index 07d4179e..65c9222a 100644
--- 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 3578e8ef..c242f901 100644
--- 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 ce4a493e..fafcd340 100644
--- 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) {