summaryrefslogtreecommitdiff
path: root/sshd.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2004-06-26 08:16:31 +1000
committerDamien Miller <djm@mindrot.org>2004-06-26 08:16:31 +1000
commit035a5b47cc29f9d343153d4d7c09c20ebd0eff52 (patch)
tree0b4a855e2b37b8a4e1b99a9eb2b58a45f3abc482 /sshd.c
parentaedc1d6a3ed351d11514b9bdf52456ff27dc16bc (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.c42
1 files changed, 28 insertions, 14 deletions
diff --git a/sshd.c b/sshd.c
index 015eeac9a..e5f54cbe6 100644
--- a/sshd.c
+++ b/sshd.c
@@ -42,7 +42,7 @@
42 */ 42 */
43 43
44#include "includes.h" 44#include "includes.h"
45RCSID("$OpenBSD: sshd.c,v 1.295 2004/06/25 01:16:09 djm Exp $"); 45RCSID("$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
101extern char *__progname; 107extern 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 /*