diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2007-09-04 03:21:04 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2007-09-04 03:21:04 +0000 |
commit | d7067fb3b07fcd126a7ce12a306be16786521449 (patch) | |
tree | fa37c14426ccb2ac22b918da1656202ef60e58d9 | |
parent | 02aa0db84899fd91a6631852f9dbaea400933ff2 (diff) |
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-- | usr.bin/ssh/clientloop.c | 23 | ||||
-rw-r--r-- | usr.bin/ssh/monitor.c | 7 | ||||
-rw-r--r-- | usr.bin/ssh/monitor_fdpass.c | 44 | ||||
-rw-r--r-- | usr.bin/ssh/monitor_fdpass.h | 4 | ||||
-rw-r--r-- | usr.bin/ssh/monitor_wrap.c | 7 | ||||
-rw-r--r-- | usr.bin/ssh/ssh.c | 9 |
6 files changed, 63 insertions, 31 deletions
diff --git a/usr.bin/ssh/clientloop.c b/usr.bin/ssh/clientloop.c index 546dce1bbb1..f4d7a03717d 100644 --- a/usr.bin/ssh/clientloop.c +++ b/usr.bin/ssh/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.181 2007/08/15 08:14:46 markus Exp $ */ +/* $OpenBSD: clientloop.c,v 1.182 2007/09/04 03:21:03 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -714,7 +714,7 @@ client_process_control(fd_set *readset) struct sockaddr_storage addr; struct confirm_ctx *cctx; char *cmd; - u_int i, len, env_len, command, flags; + u_int i, j, len, env_len, command, flags; uid_t euid; gid_t egid; @@ -862,9 +862,22 @@ client_process_control(fd_set *readset) xfree(cmd); /* Gather fds from client */ - new_fd[0] = mm_receive_fd(client_fd); - new_fd[1] = mm_receive_fd(client_fd); - new_fd[2] = mm_receive_fd(client_fd); + for(i = 0; i < 3; i++) { + if ((new_fd[i] = mm_receive_fd(client_fd)) == -1) { + error("%s: failed to receive fd %d from slave", + __func__, i); + for (j = 0; j < i; j++) + close(new_fd[j]); + for (j = 0; j < env_len; j++) + xfree(cctx->env[j]); + if (env_len > 0) + xfree(cctx->env); + xfree(cctx->term); + buffer_free(&cctx->cmd); + xfree(cctx); + return; + } + } debug2("%s: got fds stdin %d, stdout %d, stderr %d", __func__, new_fd[0], new_fd[1], new_fd[2]); diff --git a/usr.bin/ssh/monitor.c b/usr.bin/ssh/monitor.c index ab89de60938..ed32d2c105c 100644 --- a/usr.bin/ssh/monitor.c +++ b/usr.bin/ssh/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.91 2007/05/17 20:52:13 djm Exp $ */ +/* $OpenBSD: monitor.c,v 1.92 2007/09/04 03:21:03 djm Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -1105,8 +1105,9 @@ mm_answer_pty(int sock, Buffer *m) mm_request_send(sock, MONITOR_ANS_PTY, m); - mm_send_fd(sock, s->ptyfd); - mm_send_fd(sock, s->ttyfd); + if (mm_send_fd(sock, s->ptyfd) == -1 || + mm_send_fd(sock, s->ttyfd) == -1) + fatal("%s: send fds failed", __func__); /* make sure nothing uses fd 0 */ if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) diff --git a/usr.bin/ssh/monitor_fdpass.c b/usr.bin/ssh/monitor_fdpass.c index cb2001e6d41..c760a2150b0 100644 --- a/usr.bin/ssh/monitor_fdpass.c +++ b/usr.bin/ssh/monitor_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.c,v 1.12 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.13 2007/09/04 03:21:03 djm Exp $ */ /* * Copyright 2001 Niels Provos <provos@citi.umich.edu> * All rights reserved. @@ -35,7 +35,7 @@ #include "log.h" #include "monitor_fdpass.h" -void +int mm_send_fd(int sock, int fd) { struct msghdr msg; @@ -59,12 +59,18 @@ mm_send_fd(int sock, int fd) msg.msg_iov = &vec; msg.msg_iovlen = 1; - if ((n = sendmsg(sock, &msg, 0)) == -1) - fatal("%s: sendmsg(%d): %s", __func__, fd, + if ((n = sendmsg(sock, &msg, 0)) == -1) { + error("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); - if (n != 1) - fatal("%s: sendmsg: expected sent 1 got %ld", + return -1; + } + + if (n != 1) { + error("%s: sendmsg: expected sent 1 got %ld", __func__, (long)n); + return -1; + } + return 0; } int @@ -86,18 +92,28 @@ mm_receive_fd(int sock) msg.msg_control = tmp; msg.msg_controllen = sizeof(tmp); - if ((n = recvmsg(sock, &msg, 0)) == -1) - fatal("%s: recvmsg: %s", __func__, strerror(errno)); - if (n != 1) - fatal("%s: recvmsg: expected received 1 got %ld", + if ((n = recvmsg(sock, &msg, 0)) == -1) { + error("%s: recvmsg: %s", __func__, strerror(errno)); + return -1; + } + + if (n != 1) { + error("%s: recvmsg: expected received 1 got %ld", __func__, (long)n); + return -1; + } cmsg = CMSG_FIRSTHDR(&msg); - if (cmsg == NULL) - fatal("%s: no message header", __func__); - if (cmsg->cmsg_type != SCM_RIGHTS) - fatal("%s: expected type %d got %d", __func__, + if (cmsg == NULL) { + error("%s: no message header", __func__); + return -1; + } + + if (cmsg->cmsg_type != SCM_RIGHTS) { + error("%s: expected type %d got %d", __func__, SCM_RIGHTS, cmsg->cmsg_type); + return -1; + } fd = (*(int *)CMSG_DATA(cmsg)); return fd; } diff --git a/usr.bin/ssh/monitor_fdpass.h b/usr.bin/ssh/monitor_fdpass.h index 12c67ec2d1f..a4b1f635896 100644 --- a/usr.bin/ssh/monitor_fdpass.h +++ b/usr.bin/ssh/monitor_fdpass.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.h,v 1.3 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: monitor_fdpass.h,v 1.4 2007/09/04 03:21:03 djm Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> @@ -28,7 +28,7 @@ #ifndef _MM_FDPASS_H_ #define _MM_FDPASS_H_ -void mm_send_fd(int, int); +int mm_send_fd(int, int); int mm_receive_fd(int); #endif /* _MM_FDPASS_H_ */ diff --git a/usr.bin/ssh/monitor_wrap.c b/usr.bin/ssh/monitor_wrap.c index 34c9d01dd69..0e51f7eb23d 100644 --- a/usr.bin/ssh/monitor_wrap.c +++ b/usr.bin/ssh/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.57 2007/06/07 19:37:34 pvalchev Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.58 2007/09/04 03:21:03 djm Exp $ */ /* * Copyright 2002 Niels Provos <provos@citi.umich.edu> * Copyright 2002 Markus Friedl <markus@openbsd.org> @@ -676,8 +676,9 @@ mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) buffer_append(&loginmsg, msg, strlen(msg)); xfree(msg); - *ptyfd = mm_receive_fd(pmonitor->m_recvfd); - *ttyfd = mm_receive_fd(pmonitor->m_recvfd); + if ((*ptyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1 || + (*ttyfd = mm_receive_fd(pmonitor->m_recvfd)) == -1) + fatal("%s: receive fds failed", __func__); /* Success */ return (1); diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index 7f656522e95..db350e2cbb4 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.301 2007/08/07 07:32:53 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.302 2007/09/04 03:21:03 djm Exp $ */ /* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland @@ -1406,9 +1406,10 @@ control_client(const char *path) if (ssh_msg_send(sock, SSHMUX_VER, &m) == -1) fatal("%s: msg_send", __func__); - mm_send_fd(sock, STDIN_FILENO); - mm_send_fd(sock, STDOUT_FILENO); - mm_send_fd(sock, STDERR_FILENO); + if (mm_send_fd(sock, STDIN_FILENO) == -1 || + mm_send_fd(sock, STDOUT_FILENO) == -1 || + mm_send_fd(sock, STDERR_FILENO) == -1) + fatal("%s: send fds failed", __func__); /* Wait for reply, so master has a chance to gather ttymodes */ buffer_clear(&m); |