1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-02 23:52:07 +00:00

Kernel: Fix race in select

This is similar to 28e1da344d
and 4dd4dd2f3c.

The crux is that select verifies that the filedescriptor sets
are writable *before* blocking, and writes to them *after* blocking.
In the meantime, a concurrent thread can make the output buffer
unwritable, e.g. by deallocating it.
This commit is contained in:
Ben Wiederhake 2020-03-07 23:38:47 +01:00 committed by Andreas Kling
parent 36ba0a35ee
commit d8cd4e4902

View file

@ -2815,6 +2815,17 @@ int Process::sys$select(const Syscall::SC_select_params* params)
if (!timeout || select_has_timeout) {
if (Thread::current->block<Thread::SelectBlocker>(computed_timeout, select_has_timeout, rfds, wfds, efds) != Thread::BlockResult::WokeNormally)
return -EINTR;
// While we blocked, the process lock was dropped. This gave other threads
// the opportunity to mess with the memory. For example, it could free the
// region, and map it to a region to which it has no write permissions.
// Therefore, we need to re-validate all pointers.
if (writefds && !validate_write_typed(writefds))
return -EFAULT;
if (readfds && !validate_write_typed(readfds))
return -EFAULT;
// See the fixme below.
if (exceptfds && !validate_write_typed(exceptfds))
return -EFAULT;
}
int marked_fd_count = 0;