From 895a050e04f19f0bed2b227f67902187daf09409 Mon Sep 17 00:00:00 2001 From: Jakub Berkop Date: Fri, 18 Feb 2022 22:12:35 +0100 Subject: [PATCH] Kernel: Fixed argument passing for profiling_enable syscall Arguments larger than 32bit need to be passed as a pointer on a 32bit architectures. sys$profiling_enable has u64 event_mask argument, which means that it needs to be passed as an pointer. Previously upper 32bits were filled by garbage. --- Kernel/Process.h | 2 +- Kernel/Syscalls/profiling.cpp | 6 +++++- Kernel/init.cpp | 3 ++- Userland/Libraries/LibC/serenity.cpp | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/Kernel/Process.h b/Kernel/Process.h index 092df9f8af..1043901d34 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -390,7 +390,7 @@ public: ErrorOr sys$getrandom(Userspace, size_t, unsigned int); ErrorOr sys$getkeymap(Userspace); ErrorOr sys$setkeymap(Userspace); - ErrorOr sys$profiling_enable(pid_t, u64); + ErrorOr sys$profiling_enable(pid_t, Userspace); ErrorOr sys$profiling_disable(pid_t); ErrorOr sys$profiling_free_buffer(pid_t); ErrorOr sys$futex(Userspace); diff --git a/Kernel/Syscalls/profiling.cpp b/Kernel/Syscalls/profiling.cpp index 251eee7a5c..3c154f148b 100644 --- a/Kernel/Syscalls/profiling.cpp +++ b/Kernel/Syscalls/profiling.cpp @@ -16,11 +16,15 @@ bool g_profiling_all_threads; PerformanceEventBuffer* g_global_perf_events; u64 g_profiling_event_mask; -ErrorOr Process::sys$profiling_enable(pid_t pid, u64 event_mask) +// NOTE: event_mask needs to be passed as a pointer as u64 +// does not fit into a register on 32bit architectures. +ErrorOr Process::sys$profiling_enable(pid_t pid, Userspace userspace_event_mask) { VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this) TRY(require_no_promises()); + const auto event_mask = TRY(copy_typed_from_user(userspace_event_mask)); + if (pid == -1) { if (!is_superuser()) return EPERM; diff --git a/Kernel/init.cpp b/Kernel/init.cpp index 9a7da70dfa..50828444fc 100644 --- a/Kernel/init.cpp +++ b/Kernel/init.cpp @@ -373,7 +373,8 @@ void init_stage2(void*) if (boot_profiling) { dbgln("Starting full system boot profiling"); MutexLocker mutex_locker(Process::current().big_lock()); - auto result = Process::current().sys$profiling_enable(-1, ~0ull); + const auto enable_all = ~(u64)0; + auto result = Process::current().sys$profiling_enable(-1, reinterpret_cast(&enable_all)); VERIFY(!result.is_error()); } diff --git a/Userland/Libraries/LibC/serenity.cpp b/Userland/Libraries/LibC/serenity.cpp index 739c8fc8fd..e67e98e284 100644 --- a/Userland/Libraries/LibC/serenity.cpp +++ b/Userland/Libraries/LibC/serenity.cpp @@ -22,7 +22,7 @@ int disown(pid_t pid) int profiling_enable(pid_t pid, uint64_t event_mask) { - int rc = syscall(SC_profiling_enable, pid, event_mask); + int rc = syscall(SC_profiling_enable, pid, &event_mask); __RETURN_WITH_ERRNO(rc, rc, -1); }