Kernel: Fix race in waitid
This is similar to28e1da344d
and4dd4dd2f3c
. 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:
parent
d8cd4e4902
commit
b066586355
Notes:
sideshowbarker
2024-07-19 08:49:59 +09:00
Author: https://github.com/BenWiederhake Commit: https://github.com/SerenityOS/serenity/commit/b0665863555 Pull-request: https://github.com/SerenityOS/serenity/pull/1384
1 changed files with 6 additions and 0 deletions
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue