1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 09:48:11 +00:00

LibCore: Fix signal handling race condition in EventLoop

The event loop is responsible for handling POSIX signals while it's
running. The signal handler adds the signals to a wake pipe which is
then read after the select'ing code in wait_for_event. Problems happen,
however, when another signal comes in after the select wake: the signal
will interrupt the next syscall, the `read` from the wake pipe, and the
resulting EINTR in wait_for_event causes the program to crash. This is
undesirable. Instead, we want to retry reading as long as we're
interrupted.
This commit is contained in:
kleines Filmröllchen 2022-01-21 13:23:57 +01:00 committed by Andreas Kling
parent a501b9c7df
commit 888faa3c9f

View file

@ -5,6 +5,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <AK/Assertions.h>
#include <AK/Badge.h>
#include <AK/Debug.h>
#include <AK/Format.h>
@ -675,9 +676,17 @@ try_select_again:
}
if (FD_ISSET(s_wake_pipe_fds[0], &rfds)) {
int wake_events[8];
auto nread = read(s_wake_pipe_fds[0], wake_events, sizeof(wake_events));
ssize_t nread;
// We might receive another signal while read()ing here. The signal will go to the handle_signal properly,
// but we get interrupted. Therefore, just retry while we were interrupted.
do {
errno = 0;
nread = read(s_wake_pipe_fds[0], wake_events, sizeof(wake_events));
if (nread == 0)
break;
} while (nread < 0 && errno == EINTR);
if (nread < 0) {
perror("read from wake pipe");
perror("Core::EventLoop::wait_for_event: read from wake pipe");
VERIFY_NOT_REACHED();
}
VERIFY(nread > 0);