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
This commit is contained in:
dtucker@openbsd.org 2016-11-30 00:28:31 +00:00 committed by Damien Miller
parent c9f880c195
commit 7fc4766ac7
3 changed files with 29 additions and 9 deletions

20
misc.c
View File

@ -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;
}

3
misc.h
View File

@ -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 {

15
sshd.c
View File

@ -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) {