diff options
author | Jon Simons <jon@jonsimons.org> | 2013-10-31 04:17:38 -0700 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2013-10-31 12:45:21 +0100 |
commit | 20caa68b8458471212f16a86890546eac3a71fdd (patch) | |
tree | 7666d3584a8c84eb094e7c7d5655c54629ff6dab /src | |
parent | b00a6e3885a39290f52b3b37e65053a580788bf8 (diff) | |
download | libssh-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')
-rw-r--r-- | src/connect.c | 11 |
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; } |