]> git.ipfire.org Git - thirdparty/openssh-portable.git/commitdiff
Only return events from ppoll that were requested.
authorDarren Tucker <dtucker@dtucker.net>
Fri, 1 Apr 2022 12:38:44 +0000 (23:38 +1100)
committerDarren Tucker <dtucker@dtucker.net>
Fri, 1 Apr 2022 12:38:44 +0000 (23:38 +1100)
If the underlying system's select() returns bits that were not in the
request set, our ppoll() implementation can return revents for events
not requested, which can apparently cause a hang.  Only return revents
for activity in the requested event set.  bz#3416, analysis and fix by
yaroslav.kuzmin at vmssoftware com, ok djm@

openbsd-compat/bsd-poll.c

index 781ee978a651c150ec754ca7d82aa38a6dfbb9ee..9a9794f5863be1509765a9f7c6e1cc9a936444df 100644 (file)
@@ -91,11 +91,11 @@ ppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmoutp,
                fds[i].revents = 0;
                if (fd == -1)
                        continue;
-               if (FD_ISSET(fd, readfds))
+               if ((fds[i].events & POLLIN) && FD_ISSET(fd, readfds))
                        fds[i].revents |= POLLIN;
-               if (FD_ISSET(fd, writefds))
+               if ((fds[i].events & POLLOUT) && FD_ISSET(fd, writefds))
                        fds[i].revents |= POLLOUT;
-               if (FD_ISSET(fd, exceptfds))
+               if ((fds[i].events & POLLPRI) && FD_ISSET(fd, exceptfds))
                        fds[i].revents |= POLLPRI;
        }