- OpenBSD CVS Sync

- djm@cvs.openbsd.org 2004/06/25 18:43:36
     [sshd.c]
     fix broken fd handling in the re-exec fallback path, particularly when
     /dev/crypto is in use; ok deraadt@ markus@
This commit is contained in:
Damien Miller 2004-06-26 08:16:31 +10:00
parent aedc1d6a3e
commit 035a5b47cc
2 changed files with 36 additions and 15 deletions

View File

@ -1,3 +1,10 @@
20040626
- (djm) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2004/06/25 18:43:36
[sshd.c]
fix broken fd handling in the re-exec fallback path, particularly when
/dev/crypto is in use; ok deraadt@ markus@
20040625 20040625
- (dtucker) OpenBSD CVS Sync - (dtucker) OpenBSD CVS Sync
- djm@cvs.openbsd.org 2004/06/24 19:30:54 - djm@cvs.openbsd.org 2004/06/24 19:30:54
@ -1423,4 +1430,4 @@
- (djm) Trim deprecated options from INSTALL. Mention UsePAM - (djm) Trim deprecated options from INSTALL. Mention UsePAM
- (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu - (djm) Fix quote handling in sftp; Patch from admorten AT umich.edu
$Id: ChangeLog,v 1.3450 2004/06/25 07:06:02 dtucker Exp $ $Id: ChangeLog,v 1.3451 2004/06/25 22:16:31 djm Exp $

42
sshd.c
View File

@ -42,7 +42,7 @@
*/ */
#include "includes.h" #include "includes.h"
RCSID("$OpenBSD: sshd.c,v 1.295 2004/06/25 01:16:09 djm Exp $"); RCSID("$OpenBSD: sshd.c,v 1.296 2004/06/25 18:43:36 djm Exp $");
#include <openssl/dh.h> #include <openssl/dh.h>
#include <openssl/bn.h> #include <openssl/bn.h>
@ -97,6 +97,12 @@ int deny_severity = LOG_WARNING;
#define O_NOCTTY 0 #define O_NOCTTY 0
#endif #endif
/* Re-exec fds */
#define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1)
#define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2)
#define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3)
#define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4)
#ifdef HAVE___PROGNAME #ifdef HAVE___PROGNAME
extern char *__progname; extern char *__progname;
#else #else
@ -1016,7 +1022,9 @@ main(int ac, char **av)
if (rexec_flag && (av[0] == NULL || *av[0] != '/')) if (rexec_flag && (av[0] == NULL || *av[0] != '/'))
fatal("sshd re-exec requires execution with an absolute path"); fatal("sshd re-exec requires execution with an absolute path");
if (rexeced_flag) if (rexeced_flag)
closefrom(STDERR_FILENO + 3); closefrom(REEXEC_MIN_FREE_FD);
else
closefrom(REEXEC_DEVCRYPTO_RESERVED_FD);
SSLeay_add_all_algorithms(); SSLeay_add_all_algorithms();
channel_set_af(IPv4or6); channel_set_af(IPv4or6);
@ -1056,7 +1064,7 @@ main(int ac, char **av)
/* Fetch our configuration */ /* Fetch our configuration */
buffer_init(&cfg); buffer_init(&cfg);
if (rexeced_flag) if (rexeced_flag)
recv_rexec_state(STDERR_FILENO + 2, &cfg); recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg);
else else
load_server_config(config_file_name, &cfg); load_server_config(config_file_name, &cfg);
@ -1235,11 +1243,11 @@ main(int ac, char **av)
startup_pipe = -1; startup_pipe = -1;
if (rexeced_flag) { if (rexeced_flag) {
close(STDERR_FILENO + 2); close(REEXEC_CONFIG_PASS_FD);
sock_in = sock_out = dup(STDIN_FILENO); sock_in = sock_out = dup(STDIN_FILENO);
if (!debug_flag) { if (!debug_flag) {
startup_pipe = dup(STDERR_FILENO + 1); startup_pipe = dup(REEXEC_STARTUP_PIPE_FD);
close(STDERR_FILENO + 1); close(REEXEC_STARTUP_PIPE_FD);
} }
} else { } else {
sock_in = dup(STDIN_FILENO); sock_in = dup(STDIN_FILENO);
@ -1501,6 +1509,7 @@ main(int ac, char **av)
sock_in = newsock; sock_in = newsock;
sock_out = newsock; sock_out = newsock;
log_init(__progname, options.log_level, options.log_facility, log_stderr); log_init(__progname, options.log_level, options.log_facility, log_stderr);
close(config_s[0]);
break; break;
} }
} }
@ -1545,35 +1554,40 @@ main(int ac, char **av)
if (rexec_flag) { if (rexec_flag) {
int fd; int fd;
debug("rexec newsock %d pipe %d sock %d", newsock, debug("rexec start in %d out %d newsock %d pipe %d sock %d",
startup_pipe, config_s[0]); sock_in, sock_out, newsock, startup_pipe, config_s[0]);
dup2(newsock, STDIN_FILENO); dup2(newsock, STDIN_FILENO);
dup2(STDIN_FILENO, STDOUT_FILENO); dup2(STDIN_FILENO, STDOUT_FILENO);
if (startup_pipe == -1) if (startup_pipe == -1)
close(STDERR_FILENO + 1); close(REEXEC_STARTUP_PIPE_FD);
else else
dup2(startup_pipe, STDERR_FILENO + 1); dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD);
dup2(config_s[1], STDERR_FILENO + 2); dup2(config_s[1], REEXEC_CONFIG_PASS_FD);
close(config_s[1]); close(config_s[1]);
close(startup_pipe);
execv(rexec_argv[0], rexec_argv); execv(rexec_argv[0], rexec_argv);
/* Reexec has failed, fall back and continue */ /* Reexec has failed, fall back and continue */
error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); error("rexec of %s failed: %s", rexec_argv[0], strerror(errno));
recv_rexec_state(STDERR_FILENO + 2, NULL); recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL);
log_init(__progname, options.log_level, log_init(__progname, options.log_level,
options.log_facility, log_stderr); options.log_facility, log_stderr);
/* Clean up fds */ /* Clean up fds */
startup_pipe = REEXEC_STARTUP_PIPE_FD;
close(config_s[1]); close(config_s[1]);
close(STDERR_FILENO + 1); close(REEXEC_CONFIG_PASS_FD);
close(STDERR_FILENO + 2); newsock = sock_out = sock_in = dup(STDIN_FILENO);
if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) {
dup2(fd, STDIN_FILENO); dup2(fd, STDIN_FILENO);
dup2(fd, STDOUT_FILENO); dup2(fd, STDOUT_FILENO);
if (fd > STDERR_FILENO) if (fd > STDERR_FILENO)
close(fd); close(fd);
} }
debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d",
sock_in, sock_out, newsock, startup_pipe, config_s[0]);
} }
/* /*