diff options
author | Andreas Kling <kling@serenityos.org> | 2020-12-23 14:42:22 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-12-23 14:50:20 +0100 |
commit | eaa63fdda566447f631f15f94e3054719039e5c8 (patch) | |
tree | 9541aea0f51edf914481735f317a96dfe0d542e9 /Kernel | |
parent | c25cf5fb5680389dadadd98fae19bcd7d96386ca (diff) | |
download | serenity-eaa63fdda566447f631f15f94e3054719039e5c8.zip |
Kernel: Don't assert on PT_PEEK with kernelspace address
We were casting the address to Userspace<T> without validating it first
which is no good and will trap an assertion soon after.
Let's catch this sooner with an ASSERT in the Userspace<T> constructor
and update the PT_PEEK and PT_POKE handlers to avoid it.
Fixes #4505.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Ptrace.cpp | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/Kernel/Ptrace.cpp b/Kernel/Ptrace.cpp index 61b6028670..656e200606 100644 --- a/Kernel/Ptrace.cpp +++ b/Kernel/Ptrace.cpp @@ -129,21 +129,20 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P Kernel::Syscall::SC_ptrace_peek_params peek_params; if (!copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr))) return -EFAULT; - - // read validation is done inside 'peek_user_data' - auto result = peer->process().peek_user_data((FlatPtr)peek_params.address); - if (result.is_error()) + if (!is_user_address(VirtualAddress { peek_params.address })) return -EFAULT; + auto result = peer->process().peek_user_data(Userspace<const u32*> { (FlatPtr)peek_params.address }); + if (result.is_error()) + return result.error(); if (!copy_to_user(peek_params.out_data, &result.value())) return -EFAULT; break; } - case PT_POKE: { - Userspace<u32*> addr = reinterpret_cast<FlatPtr>(params.addr); - // write validation is done inside 'poke_user_data' - return peer->process().poke_user_data(addr, params.data); - } + case PT_POKE: + if (!is_user_address(VirtualAddress { params.addr })) + return -EFAULT; + return peer->process().poke_user_data(Userspace<u32*> { (FlatPtr)params.addr }, params.data); default: return -EINVAL; |