From 639cb8ab1eeee2c3192853ba7c03b6843d94734b Mon Sep 17 00:00:00 2001 From: djm Date: Wed, 10 Oct 2001 05:03:58 +0000 Subject: [PATCH] - markus@cvs.openbsd.org 2001/10/07 17:49:40 [channels.c channels.h] avoid possible FD_ISSET overflow for channels established during channnel_after_select() (used for dynamic channels). --- ChangeLog | 4 ++++ channels.c | 36 ++++++++++++++++++++++++++++-------- channels.h | 6 +++--- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index a45d4174..4d5f4d6a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -21,6 +21,10 @@ - markus@cvs.openbsd.org 2001/10/07 10:29:52 [authfile.c] grammer; Matthew_Clarke@mindlink.bc.ca + - markus@cvs.openbsd.org 2001/10/07 17:49:40 + [channels.c channels.h] + avoid possible FD_ISSET overflow for channels established + during channnel_after_select() (used for dynamic channels). 20011007 - (bal) ssh-copy-id corrected permissions for .ssh/ and authorized_keys. diff --git a/channels.c b/channels.c index 758ea506..1ec6074b 100644 --- a/channels.c +++ b/channels.c @@ -39,7 +39,7 @@ */ #include "includes.h" -RCSID("$OpenBSD: channels.c,v 1.136 2001/10/04 15:05:40 markus Exp $"); +RCSID("$OpenBSD: channels.c,v 1.137 2001/10/07 17:49:40 markus Exp $"); #include "ssh.h" #include "ssh1.h" @@ -241,6 +241,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, } /* Initialize and return new channel. */ c = channels[found] = xmalloc(sizeof(Channel)); + memset(c, 0, sizeof(Channel)); buffer_init(&c->input); buffer_init(&c->output); buffer_init(&c->extended); @@ -974,7 +975,7 @@ channel_pre_dynamic(Channel *c, fd_set * readset, fd_set * writeset) int have, ret; have = buffer_len(&c->input); - + c->delayed = 0; debug2("channel %d: pre_dynamic: have %d", c->self, have); /* buffer_dump(&c->input); */ /* check if the fixed size part of the packet is in buffer. */ @@ -1133,11 +1134,18 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) "to %.100s port %d requested.", c->listening_port, c->path, c->host_port); - rtype = (c->type == SSH_CHANNEL_RPORT_LISTENER) ? - "forwarded-tcpip" : "direct-tcpip"; - nextstate = (c->host_port == 0 && - c->type != SSH_CHANNEL_RPORT_LISTENER) ? - SSH_CHANNEL_DYNAMIC : SSH_CHANNEL_OPENING; + if (c->type == SSH_CHANNEL_RPORT_LISTENER) { + nextstate = SSH_CHANNEL_OPENING; + rtype = "forwarded-tcpip"; + } else { + if (c->host_port == 0) { + nextstate = SSH_CHANNEL_DYNAMIC; + rtype = "direct-tcpip"; + } else { + nextstate = SSH_CHANNEL_OPENING; + rtype = "direct-tcpip"; + } + } addrlen = sizeof(addr); newsock = accept(c->sock, &addr, &addrlen); @@ -1158,8 +1166,16 @@ channel_post_port_listener(Channel *c, fd_set * readset, fd_set * writeset) nc->host_port = c->host_port; strlcpy(nc->path, c->path, sizeof(nc->path)); - if (nextstate != SSH_CHANNEL_DYNAMIC) + if (nextstate == SSH_CHANNEL_DYNAMIC) { + /* + * do not call the channel_post handler until + * this flag has been reset by a pre-handler. + * otherwise the FD_ISSET calls might overflow + */ + nc->delayed = 1; + } else { port_open_helper(nc, rtype); + } } } @@ -1409,6 +1425,8 @@ channel_check_window(Channel *c) static void channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset) { + if (c->delayed) + return; channel_handle_rfd(c, readset, writeset); channel_handle_wfd(c, readset, writeset); } @@ -1416,6 +1434,8 @@ channel_post_open_1(Channel *c, fd_set * readset, fd_set * writeset) static void channel_post_open_2(Channel *c, fd_set * readset, fd_set * writeset) { + if (c->delayed) + return; channel_handle_rfd(c, readset, writeset); channel_handle_wfd(c, readset, writeset); channel_handle_efd(c, readset, writeset); diff --git a/channels.h b/channels.h index c6d1aabc..49a9df9d 100644 --- a/channels.h +++ b/channels.h @@ -32,7 +32,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* RCSID("$OpenBSD: channels.h,v 1.47 2001/10/01 21:38:53 markus Exp $"); */ +/* RCSID("$OpenBSD: channels.h,v 1.48 2001/10/07 17:49:40 markus Exp $"); */ #ifndef CHANNEL_H #define CHANNEL_H @@ -68,7 +68,6 @@ struct Channel { int type; /* channel type/state */ int self; /* my own channel identifier */ int remote_id; /* channel identifier for remote peer */ - /* peer can be reached over encrypted connection, via packet-sent */ int istate; /* input from channel (state of receive half) */ int ostate; /* output to channel (state of transmit half) */ int flags; /* close sent/rcvd */ @@ -77,7 +76,8 @@ struct Channel { int efd; /* extended fd */ int sock; /* sock fd */ int isatty; /* rfd is a tty */ - int force_drain; /* force close on iEOF */ + int force_drain; /* force close on iEOF */ + int delayed; /* fdset hack */ Buffer input; /* data read from socket, to be sent over * encrypted connection */ Buffer output; /* data received over encrypted connection for -- 2.45.2