mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 19:37:35 +00:00
Kernel: Use Userspace<T> in ptrace syscall
This commit is contained in:
parent
85b2413403
commit
1209bf82c1
4 changed files with 17 additions and 16 deletions
|
@ -447,13 +447,13 @@ struct SC_stat_params {
|
|||
struct SC_ptrace_params {
|
||||
int request;
|
||||
pid_t pid;
|
||||
u8* addr;
|
||||
Userspace<u8*> addr;
|
||||
int data;
|
||||
};
|
||||
|
||||
struct SC_ptrace_peek_params {
|
||||
u32* address;
|
||||
u32* out_data;
|
||||
Userspace<const u32*> address;
|
||||
Userspace<u32*> out_data;
|
||||
};
|
||||
|
||||
void initialize();
|
||||
|
|
|
@ -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<const Syscall::SC_ptrace_params*>);
|
||||
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<u32> peek_user_data(u32* address);
|
||||
KResult poke_user_data(u32* address, u32 data);
|
||||
KResultOr<u32> peek_user_data(Userspace<const u32*> address);
|
||||
KResult poke_user_data(Userspace<u32*> address, u32 data);
|
||||
|
||||
private:
|
||||
friend class MemoryManager;
|
||||
|
|
|
@ -98,7 +98,7 @@ KResultOr<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
|
|||
if (!tracer->has_regs())
|
||||
return KResult(-EINVAL);
|
||||
|
||||
auto* regs = reinterpret_cast<PtraceRegisters*>(params.addr);
|
||||
auto* regs = reinterpret_cast<PtraceRegisters*>(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<u32> 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<u32> 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<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)))
|
||||
if (!caller.validate_read_and_copy_typed(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(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<u32> handle_syscall(const Kernel::Syscall::SC_ptrace_params& params, P
|
|||
}
|
||||
|
||||
case PT_POKE: {
|
||||
u32* addr = reinterpret_cast<u32*>(params.addr);
|
||||
Userspace<u32*> addr = reinterpret_cast<FlatPtr>(params.addr.ptr());
|
||||
// write validation is done inside 'poke_user_data'
|
||||
return peer->process().poke_user_data(addr, params.data);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
int Process::sys$ptrace(const Syscall::SC_ptrace_params* user_params)
|
||||
int Process::sys$ptrace(Userspace<const Syscall::SC_ptrace_params*> 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<u32> Process::peek_user_data(u32* address)
|
||||
KResultOr<u32> Process::peek_user_data(Userspace<const u32*> 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<u32> Process::peek_user_data(u32* address)
|
|||
return result;
|
||||
}
|
||||
|
||||
KResult Process::poke_user_data(u32* address, u32 data)
|
||||
KResult Process::poke_user_data(Userspace<u32*> 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<SharedInodeVMObject&>(region->vmobject()).inode()));
|
||||
region->set_shared(false);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue