aboutsummaryrefslogtreecommitdiff
path: root/src/connect.c
diff options
context:
space:
mode:
authorJon Simons <jon@jonsimons.org>2013-10-31 04:17:38 -0700
committerAndreas Schneider <asn@cryptomilk.org>2013-10-31 12:45:21 +0100
commit20caa68b8458471212f16a86890546eac3a71fdd (patch)
tree7666d3584a8c84eb094e7c7d5655c54629ff6dab /src/connect.c
parentb00a6e3885a39290f52b3b37e65053a580788bf8 (diff)
downloadlibssh-20caa68b8458471212f16a86890546eac3a71fdd.tar.gz
libssh-20caa68b8458471212f16a86890546eac3a71fdd.tar.xz
libssh-20caa68b8458471212f16a86890546eac3a71fdd.zip
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>
Diffstat (limited to 'src/connect.c')
-rw-r--r--src/connect.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/src/connect.c b/src/connect.c
index f7965cbe..b299d41e 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -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,
fd_set *readfds, struct timeval *timeout) {
+ fd_set origfds;
socket_t fd;
int i,j;
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);
}
+ FD_ZERO(&origfds);
for (fd = 0; fd < maxfd ; fd++) {
if (FD_ISSET(fd, readfds)) {
ssh_event_add_fd(event, fd, POLLIN, ssh_select_cb, readfds);
+ FD_SET(fd, &origfds);
}
}
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 */
rc = ssh_event_dopoll(event,tm);
if (rc == SSH_ERROR){
- ssh_event_free(event);
- return SSH_ERROR;
+ goto out;
}
tm = ssh_timeout_update(&ts, base_tm);
firstround=0;
} while (1);
out:
+ for (fd = 0; fd < maxfd; fd++) {
+ if (FD_ISSET(fd, &origfds)) {
+ ssh_event_remove_fd(event, fd);
+ }
+ }
ssh_event_free(event);
return SSH_OK;
}