mirror of
				https://github.com/clearml/dropbear
				synced 2025-06-26 18:17:32 +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 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
 | ||||
| 					 fully initialised */ | ||||
| 
 | ||||
|  | ||||
| @ -138,6 +138,7 @@ struct Channel* newchannel(unsigned int remotechan, | ||||
| 	newchan->index = i; | ||||
| 	newchan->sent_close = newchan->recv_close = 0; | ||||
| 	newchan->sent_eof = newchan->recv_eof = 0; | ||||
| 	newchan->close_handler_done = 0; | ||||
| 
 | ||||
| 	newchan->remotechan = remotechan; | ||||
| 	newchan->transwindow = transwindow; | ||||
| @ -270,7 +271,9 @@ static void check_close(struct Channel *channel) { | ||||
| 				cbuf_getused(channel->writebuf), | ||||
| 				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->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  | ||||
| 	   retrieved) before we close things up. */ | ||||
| 	if (!channel->type->check_close	 | ||||
| 			|| channel->type->check_close(channel)) { | ||||
| 		|| channel->close_handler_done | ||||
| 		|| channel->type->check_close(channel)) { | ||||
| 		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 */ | ||||
| static void send_msg_channel_close(struct Channel *channel) { | ||||
| 
 | ||||
| 	TRACE(("enter send_msg_channel_close")) | ||||
| 	if (channel->type->closehandler) { | ||||
| 	TRACE(("enter send_msg_channel_close %p", channel)) | ||||
| 	if (channel->type->closehandler  | ||||
| 			&& !channel->close_handler_done) { | ||||
| 		channel->type->closehandler(channel); | ||||
| 		channel->close_handler_done = 1; | ||||
| 	} | ||||
| 	 | ||||
| 	CHECKCLEARTOWRITE(); | ||||
| @ -568,16 +574,17 @@ void recv_msg_channel_request() { | ||||
| 
 | ||||
| 	struct Channel *channel; | ||||
| 
 | ||||
| 	TRACE(("enter recv_msg_channel_request")) | ||||
| 	 | ||||
| 	channel = getchannel(); | ||||
| 
 | ||||
| 	TRACE(("enter recv_msg_channel_request %p", channel)) | ||||
| 
 | ||||
| 	if (channel->sent_close) { | ||||
| 		TRACE(("leave recv_msg_channel_request: already closed channel")) | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (channel->type->reqhandler) { | ||||
| 	if (channel->type->reqhandler  | ||||
| 			&& !channel->close_handler_done) { | ||||
| 		channel->type->reqhandler(channel); | ||||
| 	} else { | ||||
| 		send_msg_channel_failure(channel); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user