From 7fc4766ac78abae81ee75b22b7550720bfa28a33 Mon Sep 17 00:00:00 2001 From: "dtucker@openbsd.org" Date: Wed, 30 Nov 2016 00:28:31 +0000 Subject: [PATCH] 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 --- misc.c | 20 +++++++++++++++++++- misc.h | 3 ++- sshd.c | 15 ++++++++------- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/misc.c b/misc.c index 07d4179e479..65c9222aa8b 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 3578e8ef539..c242f9011f5 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 @@ -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 ce4a493ef88..fafcd3400b8 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 * Copyright (c) 1995 Tatu Ylonen , 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) {