mirror of
https://github.com/clearml/dropbear
synced 2025-01-31 10:57:01 +00:00
- Make sure we don't use channel-specific data after it has been freed
with a ChanType->closehandler()
This commit is contained in:
parent
fd0b05943d
commit
baa32218b0
@ -69,6 +69,10 @@ struct Channel {
|
|||||||
int sent_close, recv_close;
|
int sent_close, recv_close;
|
||||||
int recv_eof, sent_eof;
|
int recv_eof, sent_eof;
|
||||||
|
|
||||||
|
/* Set after running the ChanType-specific close hander
|
||||||
|
* to ensure we don't run it twice (nor type->checkclose()). */
|
||||||
|
int close_handler_done;
|
||||||
|
|
||||||
int initconn; /* used for TCP forwarding, whether the channel has been
|
int initconn; /* used for TCP forwarding, whether the channel has been
|
||||||
fully initialised */
|
fully initialised */
|
||||||
|
|
||||||
|
@ -138,6 +138,7 @@ struct Channel* newchannel(unsigned int remotechan,
|
|||||||
newchan->index = i;
|
newchan->index = i;
|
||||||
newchan->sent_close = newchan->recv_close = 0;
|
newchan->sent_close = newchan->recv_close = 0;
|
||||||
newchan->sent_eof = newchan->recv_eof = 0;
|
newchan->sent_eof = newchan->recv_eof = 0;
|
||||||
|
newchan->close_handler_done = 0;
|
||||||
|
|
||||||
newchan->remotechan = remotechan;
|
newchan->remotechan = remotechan;
|
||||||
newchan->transwindow = transwindow;
|
newchan->transwindow = transwindow;
|
||||||
@ -270,7 +271,9 @@ static void check_close(struct Channel *channel) {
|
|||||||
cbuf_getused(channel->writebuf),
|
cbuf_getused(channel->writebuf),
|
||||||
channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
|
channel->extrabuf ? cbuf_getused(channel->extrabuf) : 0))
|
||||||
|
|
||||||
if (!channel->flushing && channel->type->check_close
|
if (!channel->flushing
|
||||||
|
&& !channel->close_handler_done
|
||||||
|
&& channel->type->check_close
|
||||||
&& channel->type->check_close(channel))
|
&& channel->type->check_close(channel))
|
||||||
{
|
{
|
||||||
channel->flushing = 1;
|
channel->flushing = 1;
|
||||||
@ -281,7 +284,8 @@ static void check_close(struct Channel *channel) {
|
|||||||
channel, to ensure that the shell has exited (and the exit status
|
channel, to ensure that the shell has exited (and the exit status
|
||||||
retrieved) before we close things up. */
|
retrieved) before we close things up. */
|
||||||
if (!channel->type->check_close
|
if (!channel->type->check_close
|
||||||
|| channel->type->check_close(channel)) {
|
|| channel->close_handler_done
|
||||||
|
|| channel->type->check_close(channel)) {
|
||||||
close_allowed = 1;
|
close_allowed = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -363,9 +367,11 @@ static void check_in_progress(struct Channel *channel) {
|
|||||||
/* Send the close message and set the channel as closed */
|
/* Send the close message and set the channel as closed */
|
||||||
static void send_msg_channel_close(struct Channel *channel) {
|
static void send_msg_channel_close(struct Channel *channel) {
|
||||||
|
|
||||||
TRACE(("enter send_msg_channel_close"))
|
TRACE(("enter send_msg_channel_close %p", channel))
|
||||||
if (channel->type->closehandler) {
|
if (channel->type->closehandler
|
||||||
|
&& !channel->close_handler_done) {
|
||||||
channel->type->closehandler(channel);
|
channel->type->closehandler(channel);
|
||||||
|
channel->close_handler_done = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHECKCLEARTOWRITE();
|
CHECKCLEARTOWRITE();
|
||||||
@ -568,16 +574,17 @@ void recv_msg_channel_request() {
|
|||||||
|
|
||||||
struct Channel *channel;
|
struct Channel *channel;
|
||||||
|
|
||||||
TRACE(("enter recv_msg_channel_request"))
|
|
||||||
|
|
||||||
channel = getchannel();
|
channel = getchannel();
|
||||||
|
|
||||||
|
TRACE(("enter recv_msg_channel_request %p", channel))
|
||||||
|
|
||||||
if (channel->sent_close) {
|
if (channel->sent_close) {
|
||||||
TRACE(("leave recv_msg_channel_request: already closed channel"))
|
TRACE(("leave recv_msg_channel_request: already closed channel"))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->type->reqhandler) {
|
if (channel->type->reqhandler
|
||||||
|
&& !channel->close_handler_done) {
|
||||||
channel->type->reqhandler(channel);
|
channel->type->reqhandler(channel);
|
||||||
} else {
|
} else {
|
||||||
send_msg_channel_failure(channel);
|
send_msg_channel_failure(channel);
|
||||||
|
Loading…
Reference in New Issue
Block a user