Kernel+LibC: Fix ptrace for 64-bit
This makes the types used in the PT_PEEK and PT_POKE actions suitable for 64-bit platforms as well.
This commit is contained in:
parent
8292061f53
commit
38ddf301f6
Notes:
sideshowbarker
2024-07-18 00:57:31 +09:00
Author: https://github.com/itamar8910 Commit: https://github.com/SerenityOS/serenity/commit/38ddf301f63 Pull-request: https://github.com/SerenityOS/serenity/pull/10973 Reviewed-by: https://github.com/linusg ✅
6 changed files with 26 additions and 26 deletions
|
@ -461,13 +461,13 @@ struct SC_stat_params {
|
|||
struct SC_ptrace_params {
|
||||
int request;
|
||||
pid_t tid;
|
||||
u8* addr;
|
||||
int data;
|
||||
void* addr;
|
||||
FlatPtr data;
|
||||
};
|
||||
|
||||
struct SC_ptrace_peek_params {
|
||||
const u32* address;
|
||||
u32* out_data;
|
||||
const void* address;
|
||||
FlatPtr* out_data;
|
||||
};
|
||||
|
||||
struct SC_set_coredump_metadata_params {
|
||||
|
|
|
@ -480,8 +480,8 @@ public:
|
|||
m_wait_for_tracer_at_next_execve = val;
|
||||
}
|
||||
|
||||
ErrorOr<u32> peek_user_data(Userspace<const u32*> address);
|
||||
ErrorOr<void> poke_user_data(Userspace<u32*> address, u32 data);
|
||||
ErrorOr<FlatPtr> peek_user_data(Userspace<const FlatPtr*> address);
|
||||
ErrorOr<void> poke_user_data(Userspace<FlatPtr*> address, FlatPtr data);
|
||||
|
||||
void disowned_by_waiter(Process& process);
|
||||
void unblock_waiters(Thread::WaitBlocker::UnblockFlags, u8 signal = 0);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
static ErrorOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& params, Process& caller)
|
||||
static ErrorOr<FlatPtr> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& params, Process& caller)
|
||||
{
|
||||
SpinlockLocker scheduler_lock(g_scheduler_lock);
|
||||
if (params.request == PT_TRACE_ME) {
|
||||
|
@ -118,7 +118,7 @@ static ErrorOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& param
|
|||
TRY(copy_from_user(&peek_params, reinterpret_cast<Kernel::Syscall::SC_ptrace_peek_params*>(params.addr)));
|
||||
if (!Memory::is_user_address(VirtualAddress { peek_params.address }))
|
||||
return EFAULT;
|
||||
auto data = TRY(peer->process().peek_user_data(Userspace<const u32*> { (FlatPtr)peek_params.address }));
|
||||
auto data = TRY(peer->process().peek_user_data(Userspace<const FlatPtr*> { (FlatPtr)peek_params.address }));
|
||||
TRY(copy_to_user(peek_params.out_data, &data));
|
||||
break;
|
||||
}
|
||||
|
@ -126,7 +126,7 @@ static ErrorOr<u32> handle_ptrace(const Kernel::Syscall::SC_ptrace_params& param
|
|||
case PT_POKE:
|
||||
if (!Memory::is_user_address(VirtualAddress { params.addr }))
|
||||
return EFAULT;
|
||||
TRY(peer->process().poke_user_data(Userspace<u32*> { (FlatPtr)params.addr }, params.data));
|
||||
TRY(peer->process().poke_user_data(Userspace<FlatPtr*> { (FlatPtr)params.addr }, params.data));
|
||||
return 0;
|
||||
|
||||
case PT_PEEKDEBUG: {
|
||||
|
@ -166,19 +166,19 @@ bool Process::has_tracee_thread(ProcessID tracer_pid)
|
|||
return false;
|
||||
}
|
||||
|
||||
ErrorOr<u32> Process::peek_user_data(Userspace<const u32*> address)
|
||||
ErrorOr<FlatPtr> Process::peek_user_data(Userspace<const FlatPtr*> address)
|
||||
{
|
||||
// This function can be called from the context of another
|
||||
// process that called PT_PEEK
|
||||
ScopedAddressSpaceSwitcher switcher(*this);
|
||||
uint32_t data;
|
||||
FlatPtr data;
|
||||
TRY(copy_from_user(&data, address));
|
||||
return data;
|
||||
}
|
||||
|
||||
ErrorOr<void> Process::poke_user_data(Userspace<u32*> address, u32 data)
|
||||
ErrorOr<void> Process::poke_user_data(Userspace<FlatPtr*> address, FlatPtr data)
|
||||
{
|
||||
Memory::VirtualRange range = { address.vaddr(), sizeof(u32) };
|
||||
Memory::VirtualRange range = { address.vaddr(), sizeof(FlatPtr) };
|
||||
auto* region = address_space().find_region_containing(range);
|
||||
if (!region)
|
||||
return EFAULT;
|
||||
|
@ -206,9 +206,9 @@ ErrorOr<void> Process::poke_user_data(Userspace<u32*> address, u32 data)
|
|||
return copy_to_user(address, &data);
|
||||
}
|
||||
|
||||
ErrorOr<u32> Thread::peek_debug_register(u32 register_index)
|
||||
ErrorOr<FlatPtr> Thread::peek_debug_register(u32 register_index)
|
||||
{
|
||||
u32 data;
|
||||
FlatPtr data;
|
||||
switch (register_index) {
|
||||
case 0:
|
||||
data = m_debug_register_state.dr0;
|
||||
|
@ -234,7 +234,7 @@ ErrorOr<u32> Thread::peek_debug_register(u32 register_index)
|
|||
return data;
|
||||
}
|
||||
|
||||
ErrorOr<void> Thread::poke_debug_register(u32 register_index, u32 data)
|
||||
ErrorOr<void> Thread::poke_debug_register(u32 register_index, FlatPtr data)
|
||||
{
|
||||
switch (register_index) {
|
||||
case 0:
|
||||
|
|
|
@ -1011,8 +1011,8 @@ public:
|
|||
u32 signal_mask() const;
|
||||
void clear_signals();
|
||||
|
||||
ErrorOr<u32> peek_debug_register(u32 register_index);
|
||||
ErrorOr<void> poke_debug_register(u32 register_index, u32 data);
|
||||
ErrorOr<FlatPtr> peek_debug_register(u32 register_index);
|
||||
ErrorOr<void> poke_debug_register(u32 register_index, FlatPtr data);
|
||||
|
||||
void set_dump_backtrace_on_finalization() { m_dump_backtrace_on_finalization = true; }
|
||||
|
||||
|
|
|
@ -10,18 +10,18 @@
|
|||
|
||||
extern "C" {
|
||||
|
||||
int ptrace(int request, pid_t tid, void* addr, int data)
|
||||
long ptrace(int request, pid_t tid, void* addr, void* data)
|
||||
{
|
||||
// PT_PEEK needs special handling since the syscall wrapper
|
||||
// returns the peeked value as an int, which can be negative because of the cast.
|
||||
// When using PT_PEEK, the user can check if an error occurred
|
||||
// by looking at errno rather than the return value.
|
||||
|
||||
u32 out_data;
|
||||
FlatPtr out_data;
|
||||
Syscall::SC_ptrace_peek_params peek_params;
|
||||
auto is_peek_type = request == PT_PEEK || request == PT_PEEKDEBUG;
|
||||
if (is_peek_type) {
|
||||
peek_params.address = reinterpret_cast<u32*>(addr);
|
||||
peek_params.address = reinterpret_cast<FlatPtr*>(addr);
|
||||
peek_params.out_data = &out_data;
|
||||
addr = &peek_params;
|
||||
}
|
||||
|
@ -29,10 +29,10 @@ int ptrace(int request, pid_t tid, void* addr, int data)
|
|||
Syscall::SC_ptrace_params params {
|
||||
request,
|
||||
tid,
|
||||
reinterpret_cast<u8*>(addr),
|
||||
data
|
||||
addr,
|
||||
(FlatPtr)data
|
||||
};
|
||||
int rc = syscall(SC_ptrace, ¶ms);
|
||||
long rc = syscall(SC_ptrace, ¶ms);
|
||||
|
||||
if (is_peek_type) {
|
||||
if (rc < 0) {
|
||||
|
@ -40,7 +40,7 @@ int ptrace(int request, pid_t tid, void* addr, int data)
|
|||
return -1;
|
||||
}
|
||||
errno = 0;
|
||||
return static_cast<int>(out_data);
|
||||
return static_cast<long>(out_data);
|
||||
}
|
||||
|
||||
__RETURN_WITH_ERRNO(rc, rc, -1);
|
||||
|
|
|
@ -13,6 +13,6 @@ __BEGIN_DECLS
|
|||
// FIXME: PID/TID ISSUE
|
||||
// Affects the entirety of LibDebug and Userland/strace.cpp.
|
||||
// See also Kernel/Ptrace.cpp
|
||||
int ptrace(int request, pid_t tid, void* addr, int data);
|
||||
long ptrace(int request, pid_t tid, void* addr, void* data);
|
||||
|
||||
__END_DECLS
|
||||
|
|
Loading…
Add table
Reference in a new issue