tree-wide: check POLLNVAL everywhere
poll() sets POLLNVAL inside of the poll structures if an invalid fd is passed. So far we generally didn't check for that, thus not taking notice of the error. Given that this specific kind of error is generally indication of a programming error, and given that our code is embedded into our projects via NSS or because people link against our library, let's explicitly check for this and convert it to EBADF. (I ran into a busy loop because of this missing check when some of my test code accidentally closed an fd it shouldn't close, so this is a real thing)
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
45204921be
commit
dad28bffd6
@@ -305,6 +305,12 @@ int ask_password_plymouth(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pollfd[POLL_SOCKET].revents & POLLNVAL ||
|
||||
(notify >= 0 && pollfd[POLL_INOTIFY].revents & POLLNVAL)) {
|
||||
r = -EBADF;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
|
||||
(void) flush_fd(notify);
|
||||
|
||||
@@ -541,6 +547,12 @@ int ask_password_tty(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if ((pollfd[POLL_TTY].revents & POLLNVAL) ||
|
||||
(notify >= 0 && (pollfd[POLL_INOTIFY].revents & POLLNVAL))) {
|
||||
r = -EBADF;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0 && keyname) {
|
||||
(void) flush_fd(notify);
|
||||
|
||||
@@ -888,6 +900,13 @@ int ask_password_agent(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pollfd[FD_SOCKET].revents & POLLNVAL ||
|
||||
pollfd[FD_SIGNAL].revents & POLLNVAL ||
|
||||
(notify >= 0 && pollfd[FD_INOTIFY].revents & POLLNVAL)) {
|
||||
r = -EBADF;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pollfd[FD_SIGNAL].revents & POLLIN) {
|
||||
r = -EINTR;
|
||||
goto finish;
|
||||
|
||||
@@ -218,10 +218,14 @@ static bool barrier_read(Barrier *b, int64_t comp) {
|
||||
uint64_t buf;
|
||||
int r;
|
||||
|
||||
r = poll(pfd, 2, -1);
|
||||
if (r < 0 && IN_SET(errno, EAGAIN, EINTR))
|
||||
continue;
|
||||
else if (r < 0)
|
||||
r = poll(pfd, ELEMENTSOF(pfd), -1);
|
||||
if (r < 0) {
|
||||
if (IN_SET(errno, EAGAIN, EINTR))
|
||||
continue;
|
||||
goto error;
|
||||
}
|
||||
if (pfd[0].revents & POLLNVAL ||
|
||||
pfd[1].revents & POLLNVAL)
|
||||
goto error;
|
||||
|
||||
if (pfd[1].revents) {
|
||||
|
||||
@@ -334,9 +334,10 @@ static int write_to_terminal(const char *tty, const char *message) {
|
||||
k = poll(&pollfd, 1, (end - t) / USEC_PER_MSEC);
|
||||
if (k < 0)
|
||||
return -errno;
|
||||
|
||||
if (k == 0)
|
||||
return -ETIME;
|
||||
if (pollfd.revents & POLLNVAL)
|
||||
return -EBADF;
|
||||
|
||||
n = write(fd, p, left);
|
||||
if (n < 0) {
|
||||
|
||||
+12
-3
@@ -1048,10 +1048,14 @@ int varlink_wait(Varlink *v, usec_t timeout) {
|
||||
NULL);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
|
||||
if (pfd.revents & POLLNVAL)
|
||||
return -EBADF;
|
||||
|
||||
handle_revents(v, pfd.revents);
|
||||
|
||||
return r > 0 ? 1 : 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int varlink_get_fd(Varlink *v) {
|
||||
@@ -1139,9 +1143,14 @@ int varlink_flush(Varlink *v) {
|
||||
.events = POLLOUT,
|
||||
};
|
||||
|
||||
if (poll(&pfd, 1, -1) < 0)
|
||||
r = poll(&pfd, 1, -1);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
assert(r > 0);
|
||||
if (pfd.revents & POLLNVAL)
|
||||
return -EBADF;
|
||||
|
||||
handle_revents(v, pfd.revents);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user