summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Berkop <jakub.berkop@gmail.com>2022-02-18 22:12:35 +0100
committerAndreas Kling <kling@serenityos.org>2022-02-19 11:37:02 +0100
commit895a050e04f19f0bed2b227f67902187daf09409 (patch)
tree32b7cb988bb1ab0f12718026089154327927d1f8
parent0f2e18403c7093910a69985736db676f8a13cc75 (diff)
downloadserenity-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.h2
-rw-r--r--Kernel/Syscalls/profiling.cpp6
-rw-r--r--Kernel/init.cpp3
-rw-r--r--Userland/Libraries/LibC/serenity.cpp2
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);
}