diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 52cf74e84e..200e1d7fd1 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -447,13 +447,13 @@ struct SC_stat_params { struct SC_ptrace_params { int request; pid_t pid; - u8* addr; + Userspace addr; int data; }; struct SC_ptrace_peek_params { - u32* address; - u32* out_data; + Userspace address; + Userspace out_data; }; void initialize(); diff --git a/Kernel/Process.h b/Kernel/Process.h index d24ae9188a..5ecaa9cf6c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -326,7 +326,7 @@ public: int sys$unveil(const Syscall::SC_unveil_params*); int sys$perf_event(int type, FlatPtr arg1, FlatPtr arg2); int sys$get_stack_bounds(FlatPtr* stack_base, size_t* stack_size); - int sys$ptrace(const Syscall::SC_ptrace_params*); + int sys$ptrace(Userspace); int sys$sendfd(int sockfd, int fd); int sys$recvfd(int sockfd); long sys$sysconf(int name); @@ -559,8 +559,8 @@ public: m_wait_for_tracer_at_next_execve = val; } - KResultOr peek_user_data(u32* address); - KResult poke_user_data(u32* address, u32 data); + KResultOr peek_user_data(Userspace address); + KResult poke_user_data(Userspace address, u32 data); private: friend class MemoryManager; diff --git a/Kernel/Ptrace.cpp b/Kernel/Ptrace.cpp index 7fd5e3fb6c..45ec96877c 100644 --- a/Kernel/Ptrace.cpp +++ b/Kernel/Ptrace.cpp @@ -98,7 +98,7 @@ KResultOr handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P if (!tracer->has_regs()) return KResult(-EINVAL); - auto* regs = reinterpret_cast(params.addr); + auto* regs = reinterpret_cast(params.addr.unsafe_userspace_ptr()); if (!caller.validate_write_typed(regs)) return KResult(-EFAULT); copy_to_user(regs, &tracer->regs()); @@ -110,7 +110,7 @@ KResultOr handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P return KResult(-EINVAL); PtraceRegisters regs; - if (!caller.validate_read_and_copy_typed(®s, (const PtraceRegisters*)params.addr)) + if (!caller.validate_read_and_copy_typed(®s, (const PtraceRegisters*)params.addr.unsafe_userspace_ptr())) return KResult(-EFAULT); auto& peer_saved_registers = peer->get_register_dump_from_stack(); @@ -125,8 +125,9 @@ KResultOr handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P case PT_PEEK: { Kernel::Syscall::SC_ptrace_peek_params peek_params; - if (!caller.validate_read_and_copy_typed(&peek_params, reinterpret_cast(params.addr))) + if (!caller.validate_read_and_copy_typed(&peek_params, reinterpret_cast(params.addr.unsafe_userspace_ptr()))) return -EFAULT; + // read validation is done inside 'peek_user_data' auto result = peer->process().peek_user_data(peek_params.address); if (result.is_error()) @@ -138,7 +139,7 @@ KResultOr handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P } case PT_POKE: { - u32* addr = reinterpret_cast(params.addr); + Userspace addr = reinterpret_cast(params.addr.ptr()); // write validation is done inside 'poke_user_data' return peer->process().poke_user_data(addr, params.data); } diff --git a/Kernel/Syscalls/ptrace.cpp b/Kernel/Syscalls/ptrace.cpp index 35465af5f1..061d391be0 100644 --- a/Kernel/Syscalls/ptrace.cpp +++ b/Kernel/Syscalls/ptrace.cpp @@ -34,7 +34,7 @@ namespace Kernel { -int Process::sys$ptrace(const Syscall::SC_ptrace_params* user_params) +int Process::sys$ptrace(Userspace user_params) { REQUIRE_PROMISE(proc); Syscall::SC_ptrace_params params; @@ -58,10 +58,10 @@ bool Process::has_tracee_thread(int tracer_pid) const return has_tracee; } -KResultOr Process::peek_user_data(u32* address) +KResultOr Process::peek_user_data(Userspace address) { if (!MM.validate_user_read(*this, VirtualAddress(address), sizeof(u32))) { - dbg() << "Invalid address for peek_user_data: " << address; + dbg() << "Invalid address for peek_user_data: " << address.ptr(); return KResult(-EFAULT); } uint32_t result; @@ -74,12 +74,12 @@ KResultOr Process::peek_user_data(u32* address) return result; } -KResult Process::poke_user_data(u32* address, u32 data) +KResult Process::poke_user_data(Userspace address, u32 data) { // We validate for read (rather than write) because PT_POKE can write to readonly pages. // So we effectively only care that the poke operation is trying to write to user pages. if (!MM.validate_user_read(*this, VirtualAddress(address), sizeof(u32))) { - dbg() << "Invalid address for poke_user_data: " << address; + dbg() << "Invalid address for poke_user_data: " << address.ptr(); return KResult(-EFAULT); } ProcessPagingScope scope(*this); @@ -88,7 +88,7 @@ KResult Process::poke_user_data(u32* address, u32 data) ASSERT(region != nullptr); if (region->is_shared()) { // If the region is shared, we change its vmobject to a PrivateInodeVMObject - // to prevent the write operation from chaning any shared inode data + // to prevent the write operation from changing any shared inode data ASSERT(region->vmobject().is_shared_inode()); region->set_vmobject(PrivateInodeVMObject::create_with_inode(static_cast(region->vmobject()).inode())); region->set_shared(false);