diff options
author | Damien Miller <djm@mindrot.org> | 2004-06-26 08:16:31 +1000 |
---|---|---|
committer | Damien Miller <djm@mindrot.org> | 2004-06-26 08:16:31 +1000 |
commit | 035a5b47cc29f9d343153d4d7c09c20ebd0eff52 (patch) | |
tree | 0b4a855e2b37b8a4e1b99a9eb2b58a45f3abc482 /sshd.c | |
parent | aedc1d6a3ed351d11514b9bdf52456ff27dc16bc (diff) |
- 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@
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 42 |
1 files changed, 28 insertions, 14 deletions
@@ -42,7 +42,7 @@ | |||
42 | */ | 42 | */ |
43 | 43 | ||
44 | #include "includes.h" | 44 | #include "includes.h" |
45 | RCSID("$OpenBSD: sshd.c,v 1.295 2004/06/25 01:16:09 djm Exp $"); | 45 | RCSID("$OpenBSD: sshd.c,v 1.296 2004/06/25 18:43:36 djm Exp $"); |
46 | 46 | ||
47 | #include <openssl/dh.h> | 47 | #include <openssl/dh.h> |
48 | #include <openssl/bn.h> | 48 | #include <openssl/bn.h> |
@@ -97,6 +97,12 @@ int deny_severity = LOG_WARNING; | |||
97 | #define O_NOCTTY 0 | 97 | #define O_NOCTTY 0 |
98 | #endif | 98 | #endif |
99 | 99 | ||
100 | /* Re-exec fds */ | ||
101 | #define REEXEC_DEVCRYPTO_RESERVED_FD (STDERR_FILENO + 1) | ||
102 | #define REEXEC_STARTUP_PIPE_FD (STDERR_FILENO + 2) | ||
103 | #define REEXEC_CONFIG_PASS_FD (STDERR_FILENO + 3) | ||
104 | #define REEXEC_MIN_FREE_FD (STDERR_FILENO + 4) | ||
105 | |||
100 | #ifdef HAVE___PROGNAME | 106 | #ifdef HAVE___PROGNAME |
101 | extern char *__progname; | 107 | extern char *__progname; |
102 | #else | 108 | #else |
@@ -1016,7 +1022,9 @@ main(int ac, char **av) | |||
1016 | if (rexec_flag && (av[0] == NULL || *av[0] != '/')) | 1022 | if (rexec_flag && (av[0] == NULL || *av[0] != '/')) |
1017 | fatal("sshd re-exec requires execution with an absolute path"); | 1023 | fatal("sshd re-exec requires execution with an absolute path"); |
1018 | if (rexeced_flag) | 1024 | if (rexeced_flag) |
1019 | closefrom(STDERR_FILENO + 3); | 1025 | closefrom(REEXEC_MIN_FREE_FD); |
1026 | else | ||
1027 | closefrom(REEXEC_DEVCRYPTO_RESERVED_FD); | ||
1020 | 1028 | ||
1021 | SSLeay_add_all_algorithms(); | 1029 | SSLeay_add_all_algorithms(); |
1022 | channel_set_af(IPv4or6); | 1030 | channel_set_af(IPv4or6); |
@@ -1056,7 +1064,7 @@ main(int ac, char **av) | |||
1056 | /* Fetch our configuration */ | 1064 | /* Fetch our configuration */ |
1057 | buffer_init(&cfg); | 1065 | buffer_init(&cfg); |
1058 | if (rexeced_flag) | 1066 | if (rexeced_flag) |
1059 | recv_rexec_state(STDERR_FILENO + 2, &cfg); | 1067 | recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); |
1060 | else | 1068 | else |
1061 | load_server_config(config_file_name, &cfg); | 1069 | load_server_config(config_file_name, &cfg); |
1062 | 1070 | ||
@@ -1235,11 +1243,11 @@ main(int ac, char **av) | |||
1235 | 1243 | ||
1236 | startup_pipe = -1; | 1244 | startup_pipe = -1; |
1237 | if (rexeced_flag) { | 1245 | if (rexeced_flag) { |
1238 | close(STDERR_FILENO + 2); | 1246 | close(REEXEC_CONFIG_PASS_FD); |
1239 | sock_in = sock_out = dup(STDIN_FILENO); | 1247 | sock_in = sock_out = dup(STDIN_FILENO); |
1240 | if (!debug_flag) { | 1248 | if (!debug_flag) { |
1241 | startup_pipe = dup(STDERR_FILENO + 1); | 1249 | startup_pipe = dup(REEXEC_STARTUP_PIPE_FD); |
1242 | close(STDERR_FILENO + 1); | 1250 | close(REEXEC_STARTUP_PIPE_FD); |
1243 | } | 1251 | } |
1244 | } else { | 1252 | } else { |
1245 | sock_in = dup(STDIN_FILENO); | 1253 | sock_in = dup(STDIN_FILENO); |
@@ -1501,6 +1509,7 @@ main(int ac, char **av) | |||
1501 | sock_in = newsock; | 1509 | sock_in = newsock; |
1502 | sock_out = newsock; | 1510 | sock_out = newsock; |
1503 | log_init(__progname, options.log_level, options.log_facility, log_stderr); | 1511 | log_init(__progname, options.log_level, options.log_facility, log_stderr); |
1512 | close(config_s[0]); | ||
1504 | break; | 1513 | break; |
1505 | } | 1514 | } |
1506 | } | 1515 | } |
@@ -1545,35 +1554,40 @@ main(int ac, char **av) | |||
1545 | if (rexec_flag) { | 1554 | if (rexec_flag) { |
1546 | int fd; | 1555 | int fd; |
1547 | 1556 | ||
1548 | debug("rexec newsock %d pipe %d sock %d", newsock, | 1557 | debug("rexec start in %d out %d newsock %d pipe %d sock %d", |
1549 | startup_pipe, config_s[0]); | 1558 | sock_in, sock_out, newsock, startup_pipe, config_s[0]); |
1550 | dup2(newsock, STDIN_FILENO); | 1559 | dup2(newsock, STDIN_FILENO); |
1551 | dup2(STDIN_FILENO, STDOUT_FILENO); | 1560 | dup2(STDIN_FILENO, STDOUT_FILENO); |
1552 | if (startup_pipe == -1) | 1561 | if (startup_pipe == -1) |
1553 | close(STDERR_FILENO + 1); | 1562 | close(REEXEC_STARTUP_PIPE_FD); |
1554 | else | 1563 | else |
1555 | dup2(startup_pipe, STDERR_FILENO + 1); | 1564 | dup2(startup_pipe, REEXEC_STARTUP_PIPE_FD); |
1556 | 1565 | ||
1557 | dup2(config_s[1], STDERR_FILENO + 2); | 1566 | dup2(config_s[1], REEXEC_CONFIG_PASS_FD); |
1558 | close(config_s[1]); | 1567 | close(config_s[1]); |
1568 | close(startup_pipe); | ||
1569 | |||
1559 | execv(rexec_argv[0], rexec_argv); | 1570 | execv(rexec_argv[0], rexec_argv); |
1560 | 1571 | ||
1561 | /* Reexec has failed, fall back and continue */ | 1572 | /* Reexec has failed, fall back and continue */ |
1562 | error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); | 1573 | error("rexec of %s failed: %s", rexec_argv[0], strerror(errno)); |
1563 | recv_rexec_state(STDERR_FILENO + 2, NULL); | 1574 | recv_rexec_state(REEXEC_CONFIG_PASS_FD, NULL); |
1564 | log_init(__progname, options.log_level, | 1575 | log_init(__progname, options.log_level, |
1565 | options.log_facility, log_stderr); | 1576 | options.log_facility, log_stderr); |
1566 | 1577 | ||
1567 | /* Clean up fds */ | 1578 | /* Clean up fds */ |
1579 | startup_pipe = REEXEC_STARTUP_PIPE_FD; | ||
1568 | close(config_s[1]); | 1580 | close(config_s[1]); |
1569 | close(STDERR_FILENO + 1); | 1581 | close(REEXEC_CONFIG_PASS_FD); |
1570 | close(STDERR_FILENO + 2); | 1582 | newsock = sock_out = sock_in = dup(STDIN_FILENO); |
1571 | if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { | 1583 | if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { |
1572 | dup2(fd, STDIN_FILENO); | 1584 | dup2(fd, STDIN_FILENO); |
1573 | dup2(fd, STDOUT_FILENO); | 1585 | dup2(fd, STDOUT_FILENO); |
1574 | if (fd > STDERR_FILENO) | 1586 | if (fd > STDERR_FILENO) |
1575 | close(fd); | 1587 | close(fd); |
1576 | } | 1588 | } |
1589 | debug("rexec cleanup in %d out %d newsock %d pipe %d sock %d", | ||
1590 | sock_in, sock_out, newsock, startup_pipe, config_s[0]); | ||
1577 | } | 1591 | } |
1578 | 1592 | ||
1579 | /* | 1593 | /* |