]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
- markus@cvs.openbsd.org 2001/10/07 17:49:40
authorDamien Miller <djm@mindrot.org>
Wed, 10 Oct 2001 05:03:58 +0000 (15:03 +1000)
committerDamien Miller <djm@mindrot.org>
Wed, 10 Oct 2001 05:03:58 +0000 (15:03 +1000)
     [channels.c channels.h]
     avoid possible FD_ISSET overflow for channels established
     during channnel_after_select() (used for dynamic channels).

ChangeLog
channels.c
channels.h

index d125c1ad45ad5d8d2eeed90ca955af520730873c..2271b76ff7baf529037583c3fee5d1a575a4f9ef 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
    - 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.
  - Wrote replacements for strlcpy and mkdtemp
  - Released 1.0pre1
 
-$Id: ChangeLog,v 1.1591 2001/10/10 05:03:36 djm Exp $
+$Id: ChangeLog,v 1.1592 2001/10/10 05:03:58 djm Exp $
index 758ea506da0691b1bb706488c2e229be46683325..1ec6074b51a689eaec06dd07ec4c9ee75587ecfb 100644 (file)
@@ -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);
index c6d1aabc744fa6231bfed283589837b89fb9f4a9..49a9df9dd7dd37f4d8731e4bd6a02c19632156cd 100644 (file)
@@ -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