summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2010-01-08 17:08:00 +1100
committerDarren Tucker <dtucker@zip.com.au>2010-01-08 17:08:00 +1100
commit876045b0fb273ee11b02c535833b076c875253dc (patch)
tree372ba1e8310e20e1874a5aac76ed3a7194aec9cb /channels.c
parent6e7fe1c01b8a69099ffc42e653cc478509e84781 (diff)
- markus@cvs.openbsd.org 2009/11/11 21:37:03
[channels.c channels.h] fix race condition in x11/agent channel allocation: don't read after the end of the select read/write fdset and make sure a reused FD is not touched before the pre-handlers are called. with and ok djm@
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c26
1 files changed, 11 insertions, 15 deletions
diff --git a/channels.c b/channels.c
index eb0c61d8b..949392390 100644
--- a/channels.c
+++ b/channels.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: channels.c,v 1.298 2009/11/10 04:30:44 dtucker Exp $ */ 1/* $OpenBSD: channels.c,v 1.299 2009/11/11 21:37:03 markus 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
@@ -331,6 +331,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd,
331 c->output_filter = NULL; 331 c->output_filter = NULL;
332 c->filter_ctx = NULL; 332 c->filter_ctx = NULL;
333 c->filter_cleanup = NULL; 333 c->filter_cleanup = NULL;
334 c->delayed = 1; /* prevent call to channel_post handler */
334 TAILQ_INIT(&c->status_confirms); 335 TAILQ_INIT(&c->status_confirms);
335 debug("channel %d: new [%s]", found, remote_name); 336 debug("channel %d: new [%s]", found, remote_name);
336 return c; 337 return c;
@@ -1228,7 +1229,6 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
1228 int ret; 1229 int ret;
1229 1230
1230 have = buffer_len(&c->input); 1231 have = buffer_len(&c->input);
1231 c->delayed = 0;
1232 debug2("channel %d: pre_dynamic: have %d", c->self, have); 1232 debug2("channel %d: pre_dynamic: have %d", c->self, have);
1233 /* buffer_dump(&c->input); */ 1233 /* buffer_dump(&c->input); */
1234 /* check if the fixed size part of the packet is in buffer. */ 1234 /* check if the fixed size part of the packet is in buffer. */
@@ -1432,16 +1432,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset)
1432 if (c->path != NULL) 1432 if (c->path != NULL)
1433 nc->path = xstrdup(c->path); 1433 nc->path = xstrdup(c->path);
1434 1434
1435 if (nextstate == SSH_CHANNEL_DYNAMIC) { 1435 if (nextstate != SSH_CHANNEL_DYNAMIC)
1436 /*
1437 * do not call the channel_post handler until
1438 * this flag has been reset by a pre-handler.
1439 * otherwise the FD_ISSET calls might overflow
1440 */
1441 nc->delayed = 1;
1442 } else {
1443 port_open_helper(nc, rtype); 1436 port_open_helper(nc, rtype);
1444 }
1445 } 1437 }
1446} 1438}
1447 1439
@@ -1786,8 +1778,6 @@ channel_check_window(Channel *c)
1786static void 1778static void
1787channel_post_open(Channel *c, fd_set *readset, fd_set *writeset) 1779channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
1788{ 1780{
1789 if (c->delayed)
1790 return;
1791 channel_handle_rfd(c, readset, writeset); 1781 channel_handle_rfd(c, readset, writeset);
1792 channel_handle_wfd(c, readset, writeset); 1782 channel_handle_wfd(c, readset, writeset);
1793 if (!compat20) 1783 if (!compat20)
@@ -1919,17 +1909,23 @@ static void
1919channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset) 1909channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
1920{ 1910{
1921 static int did_init = 0; 1911 static int did_init = 0;
1922 u_int i; 1912 u_int i, oalloc;
1923 Channel *c; 1913 Channel *c;
1924 1914
1925 if (!did_init) { 1915 if (!did_init) {
1926 channel_handler_init(); 1916 channel_handler_init();
1927 did_init = 1; 1917 did_init = 1;
1928 } 1918 }
1929 for (i = 0; i < channels_alloc; i++) { 1919 for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {
1930 c = channels[i]; 1920 c = channels[i];
1931 if (c == NULL) 1921 if (c == NULL)
1932 continue; 1922 continue;
1923 if (c->delayed) {
1924 if (ftab == channel_pre)
1925 c->delayed = 0;
1926 else
1927 continue;
1928 }
1933 if (ftab[c->type] != NULL) 1929 if (ftab[c->type] != NULL)
1934 (*ftab[c->type])(c, readset, writeset); 1930 (*ftab[c->type])(c, readset, writeset);
1935 channel_garbage_collect(c); 1931 channel_garbage_collect(c);