Skip to content

Commit 549c800

Browse files
committed
sss: handle poll events correctly in clevis-decrypt-sss
When a pin's file descriptor is closed after reading, it must be removed from the poll set. Unlike epoll (which automatically removes closed fds), poll() will continue to return events for closed fds. Additionally, poll() can return POLLHUP/POLLERR/POLLNVAL when a child process exits or encounters errors. These events must be handled to avoid infinite loops, but only when there's no data to read (POLLIN not set) - otherwise we might discard valid data from a process that wrote output then exited. This fix: - Sets closed fds to -1 in the pollfds array (poll ignores negative fds) - Handles error/hangup events by cleaning up failed pins, but only when POLLIN is not set, ensuring we read all available data first
1 parent 726fcdc commit 549c800

1 file changed

Lines changed: 17 additions & 1 deletion

File tree

src/pins/sss/clevis-decrypt-sss.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,22 @@ main(int argc, char *argv[])
227227
}
228228
if (pi >= nfds)
229229
continue;
230-
if (!(pollfds[pi].revents & (POLLIN | POLLPRI)))
230+
231+
/* If no data available but pipe closed/errored, mark as failed */
232+
if (!(pollfds[pi].revents & (POLLIN | POLLPRI))) {
233+
if (pollfds[pi].revents & (POLLERR | POLLHUP | POLLNVAL)) {
234+
fclose(pin->file);
235+
pin->file = NULL;
236+
pollfds[pi].fd = -1;
237+
waitpid(pin->pid, NULL, 0);
238+
pin->pid = 0;
239+
pin->next->prev = pin->prev;
240+
pin->prev->next = pin->next;
241+
free(pin);
242+
break;
243+
}
231244
continue;
245+
}
232246

233247
{
234248
const size_t ptl = pl * 2;
@@ -260,6 +274,8 @@ main(int argc, char *argv[])
260274

261275
fclose(pin->file);
262276
pin->file = NULL;
277+
/* Remove closed fd from poll set (poll ignores negative fds) */
278+
pollfds[pi].fd = -1;
263279

264280
waitpid(pin->pid, NULL, 0);
265281
pin->pid = 0;

0 commit comments

Comments
 (0)