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.
This commit is contained in:
Augustin Cavalier
2024-07-16 19:20:34 -04:00
parent e21aac37e7
commit e763eb55ee
@@ -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);
}