summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2001-10-10 07:03:58 +0200
committerDamien Miller <djm@mindrot.org>2001-10-10 07:03:58 +0200
commit4623a754624624523ef2f50ba8647cad7f31d992 (patch)
tree15191803247f8fcc963b1b7b62989d90a7b84f33
parent - markus@cvs.openbsd.org 2001/10/07 10:29:52 (diff)
downloadopenssh-4623a754624624523ef2f50ba8647cad7f31d992.tar.xz
openssh-4623a754624624523ef2f50ba8647cad7f31d992.zip
- 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).
-rw-r--r--ChangeLog6
-rw-r--r--channels.c36
-rw-r--r--channels.h6
3 files changed, 36 insertions, 12 deletions
diff --git a/ChangeLog b/ChangeLog
index d125c1ad4..2271b76ff 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.
@@ -6666,4 +6670,4 @@
- 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 $
diff --git a/channels.c b/channels.c
index 758ea506d..1ec6074b5 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 c6d1aabc7..49a9df9dd 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