1
0
mirror of https://git.libssh.org/projects/libssh.git synced 2025-11-29 01:03:57 +03:00

connect: fix memory leak in ssh_select

Balance 'ssh_event_add_fd' with 'ssh_event_remove_fd' in 'ssh_select'.

BUG: https://red.libssh.org/issues/128

Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
This commit is contained in:
Jon Simons
2013-10-31 04:17:38 -07:00
committed by Andreas Schneider
parent b00a6e3885
commit 20caa68b84

View File

@@ -436,6 +436,7 @@ static int ssh_select_cb (socket_t fd, int revents, void *userdata){
*/ */
int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd, int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
fd_set *readfds, struct timeval *timeout) { fd_set *readfds, struct timeval *timeout) {
fd_set origfds;
socket_t fd; socket_t fd;
int i,j; int i,j;
int rc; int rc;
@@ -449,9 +450,11 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
ssh_event_add_session(event, channels[i]->session); ssh_event_add_session(event, channels[i]->session);
} }
FD_ZERO(&origfds);
for (fd = 0; fd < maxfd ; fd++) { for (fd = 0; fd < maxfd ; fd++) {
if (FD_ISSET(fd, readfds)) { if (FD_ISSET(fd, readfds)) {
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds); ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
FD_SET(fd, &origfds);
} }
} }
outchannels[0] = NULL; outchannels[0] = NULL;
@@ -485,13 +488,17 @@ int ssh_select(ssh_channel *channels, ssh_channel *outchannels, socket_t maxfd,
/* since there's nothing, let's fire the polling */ /* since there's nothing, let's fire the polling */
rc = ssh_event_dopoll(event,tm); rc = ssh_event_dopoll(event,tm);
if (rc == SSH_ERROR){ if (rc == SSH_ERROR){
ssh_event_free(event); goto out;
return SSH_ERROR;
} }
tm = ssh_timeout_update(&ts, base_tm); tm = ssh_timeout_update(&ts, base_tm);
firstround=0; firstround=0;
} while (1); } while (1);
out: out:
for (fd = 0; fd < maxfd; fd++) {
if (FD_ISSET(fd, &origfds)) {
ssh_event_remove_fd(event, fd);
}
}
ssh_event_free(event); ssh_event_free(event);
return SSH_OK; return SSH_OK;
} }