From e763eb55eef9a94aea794f5e9bde8c9b03568459 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 16 Jul 2024 19:20:20 -0400 Subject: [PATCH] kernel/events: Check sync->set for B_EVENT_INVALID. The infos[i] will only have B_EVENT_INVALID in the case where select() returned an error and we set it ourselves; or for wait_for_objects, it will now always be set as one of the select flags, so we can't rely on it there. Failing to deselect objects (or, in the case where we did receive B_EVENT_INVALID, deselecting them again incorrectly) can cause memory corruptions and use-after-frees. Fixes at least one KDL inadvertently introduced after the previous refactorings, but the double-deselect problems predate that commit. --- src/system/kernel/events/wait_for_objects.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/system/kernel/events/wait_for_objects.cpp b/src/system/kernel/events/wait_for_objects.cpp index d142a61931..6c9d3c9597 100644 --- a/src/system/kernel/events/wait_for_objects.cpp +++ b/src/system/kernel/events/wait_for_objects.cpp @@ -624,7 +624,7 @@ common_poll(struct pollfd *fds, nfds_t numFDs, bigtime_t timeout, // deselect file descriptors for (uint32 i = 0; i < numFDs; i++) { - if (fds[i].fd >= 0 && (fds[i].revents & POLLNVAL) == 0) + if (fds[i].fd >= 0 && (sync->set[i].events & POLLNVAL) == 0) deselect_fd(fds[i].fd, sync->set + i, kernel); } @@ -704,7 +704,7 @@ common_wait_for_objects(object_wait_info* infos, int numInfos, uint32 flags, for (int i = 0; i < numInfos; i++) { uint16 type = infos[i].type; - if ((infos[i].events & B_EVENT_INVALID) == 0) + if ((sync->set[i].events & B_EVENT_INVALID) == 0) deselect_object(type, infos[i].object, sync->set + i, kernel); }