Kernel: Fix race in waitid

This is similar to 28e1da344d
and 4dd4dd2f3c.

The crux is that wait verifies that the outvalue (siginfo* infop)
is writable *before* waiting, and writes to it *after* waiting.
In the meantime, a concurrent thread can make the output region
unwritable, e.g. by deallocating it.
This commit is contained in:
Ben Wiederhake 2020-03-08 13:14:35 +01:00 committed by Andreas Kling
parent d8cd4e4902
commit b066586355
Notes: sideshowbarker 2024-07-19 08:49:59 +09:00

View file

@ -2427,6 +2427,12 @@ pid_t Process::sys$waitid(const Syscall::SC_waitid_params* user_params)
auto siginfo_or_error = do_waitid(static_cast<idtype_t>(params.idtype), params.id, params.options);
if (siginfo_or_error.is_error())
return siginfo_or_error.error();
// While we waited, 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 the pointer.
if (!validate_write_typed(params.infop))
return -EFAULT;
copy_to_user(params.infop, &siginfo_or_error.value());
return 0;