mirror of
https://git.libssh.org/projects/libssh.git
synced 2026-02-04 12:20:42 +09:00
poll: Avoid passing other events to callbacks when called recursively
Some architectures (s390x) provide different poll events such as POLLHUP in case the remote end closed the connection (and they keep reporting this forever). This is an issue when the user provided callback registering this event as an error and tries to send some reply (for example EOF) using `ssh_channel_send_eof()` which will lead to infinite recursion and sefgaults. This was not solved by the30b5a2e33bbecause the POLLHUP event is not provided by the poll in events bitfield, but only reported by the poll in revents bit field thus we need to filter these events later on when the poll is recursively. Fixes #202 Signed-off-by: Jakub Jelen <jjelen@redhat.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org> (cherry picked from commit4e56c5c956)
This commit is contained in:
committed by
Andreas Schneider
parent
4b935d0785
commit
52ebecf81c
11
src/poll.c
11
src/poll.c
@@ -722,14 +722,21 @@ int ssh_poll_ctx_dopoll(ssh_poll_ctx ctx, int timeout)
|
||||
|
||||
used = ctx->polls_used;
|
||||
for (i = 0; i < used && rc > 0; ) {
|
||||
if (ctx->pollfds[i].revents == 0) {
|
||||
revents = ctx->pollfds[i].revents;
|
||||
/* Do not pass any other events except for POLLOUT to callback when
|
||||
* called recursively more than 2 times. On s390x the poll will be
|
||||
* spammed with POLLHUP events causing infinite recursion when the user
|
||||
* callback issues some write/flush/poll calls. */
|
||||
if (ctx->pollptrs[i]->lock_cnt > 2) {
|
||||
revents &= POLLOUT;
|
||||
}
|
||||
if (revents == 0) {
|
||||
i++;
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
p = ctx->pollptrs[i];
|
||||
fd = ctx->pollfds[i].fd;
|
||||
revents = ctx->pollfds[i].revents;
|
||||
/* avoid having any event caught during callback */
|
||||
ctx->pollfds[i].events = 0;
|
||||
p->lock_cnt++;
|
||||
|
||||
Reference in New Issue
Block a user