diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index c141e62be2..80932708a1 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -4838,4 +4838,25 @@ OwnPtr Process::elf_bundle() const return bundle; } +int Process::sys$get_stack_bounds(FlatPtr* user_stack_base, size_t* user_stack_size) +{ + if (!validate_write_typed(user_stack_base)) + return -EFAULT; + if (!validate_write_typed(user_stack_size)) + return -EFAULT; + + FlatPtr stack_pointer = Thread::current->get_register_dump_from_stack().userspace_esp; + auto* stack_region = MM.region_from_vaddr(*this, VirtualAddress(stack_pointer)); + if (!stack_region) { + ASSERT_NOT_REACHED(); + return -EINVAL; + } + + FlatPtr stack_base = stack_region->range().base().get(); + size_t stack_size = stack_region->size(); + copy_to_user(user_stack_base, &stack_base); + copy_to_user(user_stack_size, &stack_size); + return 0; +} + } diff --git a/Kernel/Process.h b/Kernel/Process.h index b050c1cf28..47ba58315c 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -298,6 +298,7 @@ public: int sys$pledge(const Syscall::SC_pledge_params*); 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); template int get_sock_or_peer_name(const Params&); diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index f9b3e7384f..5cef651458 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -178,7 +178,8 @@ namespace Kernel { __ENUMERATE_SYSCALL(pledge) \ __ENUMERATE_SYSCALL(unveil) \ __ENUMERATE_SYSCALL(perf_event) \ - __ENUMERATE_SYSCALL(shutdown) + __ENUMERATE_SYSCALL(shutdown) \ + __ENUMERATE_SYSCALL(get_stack_bounds) namespace Syscall { diff --git a/Libraries/LibC/serenity.cpp b/Libraries/LibC/serenity.cpp index ce665489b8..0474e15579 100644 --- a/Libraries/LibC/serenity.cpp +++ b/Libraries/LibC/serenity.cpp @@ -124,4 +124,11 @@ int shbuf_allow_all(int shbuf_id) int rc = syscall(SC_shbuf_allow_all, shbuf_id); __RETURN_WITH_ERRNO(rc, rc, -1); } + +int get_stack_bounds(uintptr_t* user_stack_base, size_t* user_stack_size) +{ + int rc = syscall(SC_get_stack_bounds, user_stack_base, user_stack_size); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + } diff --git a/Libraries/LibC/serenity.h b/Libraries/LibC/serenity.h index 44d74d2874..cf9615a27e 100644 --- a/Libraries/LibC/serenity.h +++ b/Libraries/LibC/serenity.h @@ -68,4 +68,6 @@ int purge(int mode); int perf_event(int type, uintptr_t arg1, uintptr_t arg2); +int get_stack_bounds(uintptr_t* user_stack_base, size_t* user_stack_size); + __END_DECLS