summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2007-09-17 12:04:08 +1000
committerDamien Miller <djm@mindrot.org>2007-09-17 12:04:08 +1000
commit54fd7cf2db5327f304825e0f9aaf9af5a490a75f (patch)
tree37d1a37a4ff6a5a7b6e774937ba3703edca7bc1a
parent1d824ab2e72daf8563f6dc72f4b3638da3b91dce (diff)
- djm@cvs.openbsd.org 2007/09/04 03:21:03
[clientloop.c monitor.c monitor_fdpass.c monitor_fdpass.h] [monitor_wrap.c ssh.c] make file descriptor passing code return an error rather than call fatal() when it encounters problems, and use this to make session multiplexing masters survive slaves failing to pass all stdio FDs; ok markus@
-rw-r--r--ChangeLog8
-rw-r--r--clientloop.c23
-rw-r--r--monitor.c7
-rw-r--r--monitor_fdpass.c56
-rw-r--r--monitor_fdpass.h4
-rw-r--r--monitor_wrap.c7
-rw-r--r--ssh.c9
7 files changed, 76 insertions, 38 deletions
diff --git a/ChangeLog b/ChangeLog
index f5ee63e4f..c0a927051 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -19,6 +19,12 @@
19 - djm@cvs.openbsd.org 2007/08/23 03:23:26 19 - djm@cvs.openbsd.org 2007/08/23 03:23:26
20 [sshconnect.c] 20 [sshconnect.c]
21 Execute ProxyCommands with $SHELL rather than /bin/sh unconditionally 21 Execute ProxyCommands with $SHELL rather than /bin/sh unconditionally
22 - djm@cvs.openbsd.org 2007/09/04 03:21:03
23 [clientloop.c monitor.c monitor_fdpass.c monitor_fdpass.h]
24 [monitor_wrap.c ssh.c]
25 make file descriptor passing code return an error rather than call fatal()
26 when it encounters problems, and use this to make session multiplexing
27 masters survive slaves failing to pass all stdio FDs; ok markus@
22 28
2320070914 2920070914
24 - (dtucker) [openbsd-compat/bsd-asprintf.c] Plug mem leak in error path. 30 - (dtucker) [openbsd-compat/bsd-asprintf.c] Plug mem leak in error path.
@@ -3216,4 +3222,4 @@
3216 OpenServer 6 and add osr5bigcrypt support so when someone migrates 3222 OpenServer 6 and add osr5bigcrypt support so when someone migrates
3217 passwords between UnixWare and OpenServer they will still work. OK dtucker@ 3223 passwords between UnixWare and OpenServer they will still work. OK dtucker@
3218 3224
3219$Id: ChangeLog,v 1.4747 2007/09/17 01:58:04 djm Exp $ 3225$Id: ChangeLog,v 1.4748 2007/09/17 02:04:08 djm Exp $
diff --git a/clientloop.c b/clientloop.c
index b57fda042..7a61cb74d 100644
--- a/clientloop.c
+++ b/clientloop.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: clientloop.c,v 1.181 2007/08/15 08:14:46 markus Exp $ */ 1/* $OpenBSD: clientloop.c,v 1.182 2007/09/04 03:21:03 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -722,7 +722,7 @@ client_process_control(fd_set *readset)
722 struct sockaddr_storage addr; 722 struct sockaddr_storage addr;
723 struct confirm_ctx *cctx; 723 struct confirm_ctx *cctx;
724 char *cmd; 724 char *cmd;
725 u_int i, len, env_len, command, flags; 725 u_int i, j, len, env_len, command, flags;
726 uid_t euid; 726 uid_t euid;
727 gid_t egid; 727 gid_t egid;
728 728
@@ -870,9 +870,22 @@ client_process_control(fd_set *readset)
870 xfree(cmd); 870 xfree(cmd);
871 871
872 /* Gather fds from client */ 872 /* Gather fds from client */
873 new_fd[0] = mm_receive_fd(client_fd); 873 for(i = 0; i < 3; i++) {
874 new_fd[1] = mm_receive_fd(client_fd); 874 if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) {
875 new_fd[2] = mm_receive_fd(client_fd); 875 error("%s: failed to receive fd %d from slave",
876 __func__, i);
877 for (j = 0; j < i; j++)
878 close(new_fd[j]);
879 for (j = 0; j < env_len; j++)
880 xfree(cctx->env[j]);
881 if (env_len > 0)
882 xfree(cctx->env);
883 xfree(cctx->term);
884 buffer_free(&cctx->cmd);
885 xfree(cctx);
886 return;
887 }
888 }
876 889
877 debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, 890 debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__,
878 new_fd[0], new_fd[1], new_fd[2]); 891 new_fd[0], new_fd[1], new_fd[2]);
diff --git a/monitor.c b/monitor.c
index 08c7ea3cb..1fe1fb56f 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.91 2007/05/17 20:52:13 djm Exp $ */ 1/* $OpenBSD: monitor.c,v 1.92 2007/09/04 03:21:03 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -1314,8 +1314,9 @@ mm_answer_pty(int sock, Buffer *m)
1314 1314
1315 mm_request_send(sock, MONITOR_ANS_PTY, m); 1315 mm_request_send(sock, MONITOR_ANS_PTY, m);
1316 1316
1317 mm_send_fd(sock, s->ptyfd); 1317 if (mm_send_fd(sock, s->ptyfd) == -1 ||
1318 mm_send_fd(sock, s->ttyfd); 1318 mm_send_fd(sock, s->ttyfd) == -1)
1319 fatal("%s: send fds failed", __func__);
1319 1320
1320 /* make sure nothing uses fd 0 */ 1321 /* make sure nothing uses fd 0 */
1321 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) 1322 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0)
diff --git a/monitor_fdpass.c b/monitor_fdpass.c
index 9f8e9cd55..a572302e8 100644
--- a/monitor_fdpass.c
+++ b/monitor_fdpass.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_fdpass.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ 1/* $OpenBSD: monitor_fdpass.c,v 1.13 2007/09/04 03:21:03 djm Exp $ */
2/* 2/*
3 * Copyright 2001 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2001 Niels Provos <provos@citi.umich.edu>
4 * All rights reserved. 4 * All rights reserved.
@@ -40,7 +40,7 @@
40#include "log.h" 40#include "log.h"
41#include "monitor_fdpass.h" 41#include "monitor_fdpass.h"
42 42
43void 43int
44mm_send_fd(int sock, int fd) 44mm_send_fd(int sock, int fd)
45{ 45{
46#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) 46#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
@@ -72,15 +72,21 @@ mm_send_fd(int sock, int fd)
72 msg.msg_iov = &vec; 72 msg.msg_iov = &vec;
73 msg.msg_iovlen = 1; 73 msg.msg_iovlen = 1;
74 74
75 if ((n = sendmsg(sock, &msg, 0)) == -1) 75 if ((n = sendmsg(sock, &msg, 0)) == -1) {
76 fatal("%s: sendmsg(%d): %s", __func__, fd, 76 error("%s: sendmsg(%d): %s", __func__, fd,
77 strerror(errno)); 77 strerror(errno));
78 if (n != 1) 78 return -1;
79 fatal("%s: sendmsg: expected sent 1 got %ld", 79 }
80
81 if (n != 1) {
82 error("%s: sendmsg: expected sent 1 got %ld",
80 __func__, (long)n); 83 __func__, (long)n);
84 return -1;
85 }
86 return 0;
81#else 87#else
82 fatal("%s: UsePrivilegeSeparation=yes not supported", 88 error("%s: file descriptor passing not supported", __func__);
83 __func__); 89 return -1;
84#endif 90#endif
85} 91}
86 92
@@ -111,29 +117,39 @@ mm_receive_fd(int sock)
111 msg.msg_controllen = sizeof(tmp); 117 msg.msg_controllen = sizeof(tmp);
112#endif 118#endif
113 119
114 if ((n = recvmsg(sock, &msg, 0)) == -1) 120 if ((n = recvmsg(sock, &msg, 0)) == -1) {
115 fatal("%s: recvmsg: %s", __func__, strerror(errno)); 121 error("%s: recvmsg: %s", __func__, strerror(errno));
116 if (n != 1) 122 return -1;
117 fatal("%s: recvmsg: expected received 1 got %ld", 123 }
124 if (n != 1) {
125 error("%s: recvmsg: expected received 1 got %ld",
118 __func__, (long)n); 126 __func__, (long)n);
127 return -1;
128 }
119 129
120#ifdef HAVE_ACCRIGHTS_IN_MSGHDR 130#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
121 if (msg.msg_accrightslen != sizeof(fd)) 131 if (msg.msg_accrightslen != sizeof(fd)) {
122 fatal("%s: no fd", __func__); 132 error("%s: no fd", __func__);
133 return -1;
134 }
123#else 135#else
124 cmsg = CMSG_FIRSTHDR(&msg); 136 cmsg = CMSG_FIRSTHDR(&msg);
125 if (cmsg == NULL) 137 if (cmsg == NULL) {
126 fatal("%s: no message header", __func__); 138 error("%s: no message header", __func__);
139 return -1;
140 }
127#ifndef BROKEN_CMSG_TYPE 141#ifndef BROKEN_CMSG_TYPE
128 if (cmsg->cmsg_type != SCM_RIGHTS) 142 if (cmsg->cmsg_type != SCM_RIGHTS) {
129 fatal("%s: expected type %d got %d", __func__, 143 error("%s: expected type %d got %d", __func__,
130 SCM_RIGHTS, cmsg->cmsg_type); 144 SCM_RIGHTS, cmsg->cmsg_type);
145 return -1;
146 }
131#endif 147#endif
132 fd = (*(int *)CMSG_DATA(cmsg)); 148 fd = (*(int *)CMSG_DATA(cmsg));
133#endif 149#endif
134 return fd; 150 return fd;
135#else 151#else
136 fatal("%s: UsePrivilegeSeparation=yes not supported", 152 error("%s: file descriptor passing not supported", __func__);
137 __func__); 153 return -1;
138#endif 154#endif
139} 155}
diff --git a/monitor_fdpass.h b/monitor_fdpass.h
index 12c67ec2d..a4b1f6358 100644
--- a/monitor_fdpass.h
+++ b/monitor_fdpass.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_fdpass.h,v 1.3 2006/03/25 22:22:43 djm Exp $ */ 1/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */
2 2
3/* 3/*
4 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 4 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
@@ -28,7 +28,7 @@
28#ifndef _MM_FDPASS_H_ 28#ifndef _MM_FDPASS_H_
29#define _MM_FDPASS_H_ 29#define _MM_FDPASS_H_
30 30
31void mm_send_fd(int, int); 31int mm_send_fd(int, int);
32int mm_receive_fd(int); 32int mm_receive_fd(int);
33 33
34#endif /* _MM_FDPASS_H_ */ 34#endif /* _MM_FDPASS_H_ */
diff --git a/monitor_wrap.c b/monitor_wrap.c
index edf2814e5..36154be4d 100644
--- a/monitor_wrap.c
+++ b/monitor_wrap.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */ 1/* $OpenBSD: monitor_wrap.c,v 1.58 2007/09/04 03:21:03 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -688,8 +688,9 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen)
688 buffer_append(&loginmsg, msg, strlen(msg)); 688 buffer_append(&loginmsg, msg, strlen(msg));
689 xfree(msg); 689 xfree(msg);
690 690
691 *ptyfd = mm_receive_fd(pmonitor->m_recvfd); 691 if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 ||
692 *ttyfd = mm_receive_fd(pmonitor->m_recvfd); 692 (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1)
693 fatal("%s: receive fds failed", __func__);
693 694
694 /* Success */ 695 /* Success */
695 return (1); 696 return (1);
diff --git a/ssh.c b/ssh.c
index d3a7ffc9b..7f8ea0d17 100644
--- a/ssh.c
+++ b/ssh.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh.c,v 1.301 2007/08/07 07:32:53 djm Exp $ */ 1/* $OpenBSD: ssh.c,v 1.302 2007/09/04 03:21:03 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1426,9 +1426,10 @@ control_client(const char *path)
1426 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) 1426 if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1)
1427 fatal("%s: msg_send", __func__); 1427 fatal("%s: msg_send", __func__);
1428 1428
1429 mm_send_fd(sock, STDIN_FILENO); 1429 if (mm_send_fd(sock, STDIN_FILENO) == -1 ||
1430 mm_send_fd(sock, STDOUT_FILENO); 1430 mm_send_fd(sock, STDOUT_FILENO) == -1 ||
1431 mm_send_fd(sock, STDERR_FILENO); 1431 mm_send_fd(sock, STDERR_FILENO) == -1)
1432 fatal("%s: send fds failed", __func__);
1432 1433
1433 /* Wait for reply, so master has a chance to gather ttymodes */ 1434 /* Wait for reply, so master has a chance to gather ttymodes */
1434 buffer_clear(&m); 1435 buffer_clear(&m);