diff options
author | Jakub Berkop <jakub.berkop@gmail.com> | 2022-02-18 22:12:35 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-19 11:37:02 +0100 |
commit | 895a050e04f19f0bed2b227f67902187daf09409 (patch) | |
tree | 32b7cb988bb1ab0f12718026089154327927d1f8 | |
parent | 0f2e18403c7093910a69985736db676f8a13cc75 (diff) | |
download | serenity-895a050e04f19f0bed2b227f67902187daf09409.zip |
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.
-rw-r--r-- | Kernel/Process.h | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/profiling.cpp | 6 | ||||
-rw-r--r-- | Kernel/init.cpp | 3 | ||||
-rw-r--r-- | 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<FlatPtr> sys$getrandom(Userspace<void*>, size_t, unsigned int); ErrorOr<FlatPtr> sys$getkeymap(Userspace<const Syscall::SC_getkeymap_params*>); ErrorOr<FlatPtr> sys$setkeymap(Userspace<const Syscall::SC_setkeymap_params*>); - ErrorOr<FlatPtr> sys$profiling_enable(pid_t, u64); + ErrorOr<FlatPtr> sys$profiling_enable(pid_t, Userspace<u64 const*>); ErrorOr<FlatPtr> sys$profiling_disable(pid_t); ErrorOr<FlatPtr> sys$profiling_free_buffer(pid_t); ErrorOr<FlatPtr> sys$futex(Userspace<const Syscall::SC_futex_params*>); 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<FlatPtr> 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<FlatPtr> Process::sys$profiling_enable(pid_t pid, Userspace<u64 const*> 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<FlatPtr>(&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); } |