mirror of
https://github.com/PowerShell/openssh-portable.git
synced 2025-07-31 01:35:11 +02:00
- 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@
This commit is contained in:
parent
6e7fe1c01b
commit
876045b0fb
@ -51,6 +51,12 @@
|
|||||||
[sshconnect2.c channels.c sshconnect.c]
|
[sshconnect2.c channels.c sshconnect.c]
|
||||||
Set close-on-exec on various descriptors so they don't get leaked to
|
Set close-on-exec on various descriptors so they don't get leaked to
|
||||||
child processes. bz #1643, patch from jchadima at redhat, ok deraadt.
|
child processes. bz #1643, patch from jchadima at redhat, ok deraadt.
|
||||||
|
- 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@
|
||||||
|
|
||||||
20091226
|
20091226
|
||||||
- (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1
|
- (tim) [contrib/cygwin/Makefile] Install ssh-copy-id and ssh-copy-id.1
|
||||||
|
26
channels.c
26
channels.c
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: channels.c,v 1.298 2009/11/10 04:30:44 dtucker Exp $ */
|
/* $OpenBSD: channels.c,v 1.299 2009/11/11 21:37:03 markus Exp $ */
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
|
* 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,
|
|||||||
c->output_filter = NULL;
|
c->output_filter = NULL;
|
||||||
c->filter_ctx = NULL;
|
c->filter_ctx = NULL;
|
||||||
c->filter_cleanup = NULL;
|
c->filter_cleanup = NULL;
|
||||||
|
c->delayed = 1; /* prevent call to channel_post handler */
|
||||||
TAILQ_INIT(&c->status_confirms);
|
TAILQ_INIT(&c->status_confirms);
|
||||||
debug("channel %d: new [%s]", found, remote_name);
|
debug("channel %d: new [%s]", found, remote_name);
|
||||||
return c;
|
return c;
|
||||||
@ -1228,7 +1229,6 @@ channel_pre_dynamic(Channel *c, fd_set *readset, fd_set *writeset)
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
have = buffer_len(&c->input);
|
have = buffer_len(&c->input);
|
||||||
c->delayed = 0;
|
|
||||||
debug2("channel %d: pre_dynamic: have %d", c->self, have);
|
debug2("channel %d: pre_dynamic: have %d", c->self, have);
|
||||||
/* buffer_dump(&c->input); */
|
/* buffer_dump(&c->input); */
|
||||||
/* check if the fixed size part of the packet is in buffer. */
|
/* 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)
|
|||||||
if (c->path != NULL)
|
if (c->path != NULL)
|
||||||
nc->path = xstrdup(c->path);
|
nc->path = xstrdup(c->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);
|
port_open_helper(nc, rtype);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1786,8 +1778,6 @@ channel_check_window(Channel *c)
|
|||||||
static void
|
static void
|
||||||
channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
|
channel_post_open(Channel *c, fd_set *readset, fd_set *writeset)
|
||||||
{
|
{
|
||||||
if (c->delayed)
|
|
||||||
return;
|
|
||||||
channel_handle_rfd(c, readset, writeset);
|
channel_handle_rfd(c, readset, writeset);
|
||||||
channel_handle_wfd(c, readset, writeset);
|
channel_handle_wfd(c, readset, writeset);
|
||||||
if (!compat20)
|
if (!compat20)
|
||||||
@ -1919,17 +1909,23 @@ static void
|
|||||||
channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
|
channel_handler(chan_fn *ftab[], fd_set *readset, fd_set *writeset)
|
||||||
{
|
{
|
||||||
static int did_init = 0;
|
static int did_init = 0;
|
||||||
u_int i;
|
u_int i, oalloc;
|
||||||
Channel *c;
|
Channel *c;
|
||||||
|
|
||||||
if (!did_init) {
|
if (!did_init) {
|
||||||
channel_handler_init();
|
channel_handler_init();
|
||||||
did_init = 1;
|
did_init = 1;
|
||||||
}
|
}
|
||||||
for (i = 0; i < channels_alloc; i++) {
|
for (i = 0, oalloc = channels_alloc; i < oalloc; i++) {
|
||||||
c = channels[i];
|
c = channels[i];
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
if (c->delayed) {
|
||||||
|
if (ftab == channel_pre)
|
||||||
|
c->delayed = 0;
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (ftab[c->type] != NULL)
|
if (ftab[c->type] != NULL)
|
||||||
(*ftab[c->type])(c, readset, writeset);
|
(*ftab[c->type])(c, readset, writeset);
|
||||||
channel_garbage_collect(c);
|
channel_garbage_collect(c);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: channels.h,v 1.99 2009/10/28 16:38:18 reyk Exp $ */
|
/* $OpenBSD: channels.h,v 1.100 2009/11/11 21:37:03 markus Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
* Author: Tatu Ylonen <ylo@cs.hut.fi>
|
||||||
@ -97,7 +97,11 @@ struct Channel {
|
|||||||
int wfd_isatty; /* wfd is a tty */
|
int wfd_isatty; /* wfd is a tty */
|
||||||
int client_tty; /* (client) TTY has been requested */
|
int client_tty; /* (client) TTY has been requested */
|
||||||
int force_drain; /* force close on iEOF */
|
int force_drain; /* force close on iEOF */
|
||||||
int delayed; /* fdset hack */
|
int delayed; /* post-select handlers for newly created
|
||||||
|
* channels are delayed until the first call
|
||||||
|
* to a matching pre-select handler.
|
||||||
|
* this way post-select handlers are not
|
||||||
|
* accidenly called if a FD gets reused */
|
||||||
Buffer input; /* data read from socket, to be sent over
|
Buffer input; /* data read from socket, to be sent over
|
||||||
* encrypted connection */
|
* encrypted connection */
|
||||||
Buffer output; /* data received over encrypted connection for
|
Buffer output; /* data received over encrypted connection for
|
||||||
|
Loading…
x
Reference in New Issue
Block a user