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:
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user