diff --git a/Kernel/API/Syscall.h b/Kernel/API/Syscall.h index 0d0a0555ee..b58efd4737 100644 --- a/Kernel/API/Syscall.h +++ b/Kernel/API/Syscall.h @@ -81,6 +81,7 @@ enum class NeedsBigProcessLock { S(futex, NeedsBigProcessLock::Yes) \ S(get_dir_entries, NeedsBigProcessLock::Yes) \ S(get_process_name, NeedsBigProcessLock::Yes) \ + S(get_root_session_id, NeedsBigProcessLock::No) \ S(get_stack_bounds, NeedsBigProcessLock::No) \ S(get_thread_name, NeedsBigProcessLock::Yes) \ S(getcwd, NeedsBigProcessLock::No) \ diff --git a/Kernel/Process.h b/Kernel/Process.h index ee476ecd3f..acdc1dcbc3 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -448,6 +448,7 @@ public: ErrorOr sys$map_time_page(); ErrorOr sys$jail_create(Userspace user_params); ErrorOr sys$jail_attach(Userspace user_params); + ErrorOr sys$get_root_session_id(pid_t force_sid); template ErrorOr get_sock_or_peer_name(Params const&); diff --git a/Kernel/Syscalls/setpgid.cpp b/Kernel/Syscalls/setpgid.cpp index fffdecd749..fd7715c2b3 100644 --- a/Kernel/Syscalls/setpgid.cpp +++ b/Kernel/Syscalls/setpgid.cpp @@ -139,4 +139,25 @@ ErrorOr Process::sys$setpgid(pid_t specified_pid, pid_t specified_pgid) }); } +ErrorOr Process::sys$get_root_session_id(pid_t force_sid) +{ + pid_t sid = (force_sid == -1) ? this->sid().value() : force_sid; + if (sid == 0) + return 0; + while (true) { + auto sid_process = Process::from_pid_in_same_jail(sid); + if (!sid_process) + return ESRCH; + auto parent_pid = sid_process->ppid().value(); + auto parent_process = Process::from_pid_in_same_jail(parent_pid); + if (!parent_process) + return ESRCH; + pid_t parent_sid = parent_process->sid().value(); + if (parent_sid == 0) + break; + sid = parent_sid; + } + return sid; +} + } diff --git a/Userland/Libraries/LibCore/SessionManagement.cpp b/Userland/Libraries/LibCore/SessionManagement.cpp index fb78e5dfae..a12fef8210 100644 --- a/Userland/Libraries/LibCore/SessionManagement.cpp +++ b/Userland/Libraries/LibCore/SessionManagement.cpp @@ -5,37 +5,26 @@ */ #include -#include #include #include +#ifdef AK_OS_SERENITY +# include +#endif + namespace Core::SessionManagement { -static ErrorOr get_proc(Core::AllProcessesStatistics const& stats, pid_t pid) +ErrorOr root_session_id([[maybe_unused]] Optional force_sid) { - for (auto& proc : stats.processes) { - if (proc.pid == pid) - return &proc; +#ifdef AK_OS_SERENITY + int rc = syscall(SC_get_root_session_id, force_sid.value_or(-1)); + if (rc < 0) { + return Error::from_syscall("get_root_session_id"sv, rc); } - return Error::from_string_literal("Could not find pid in process statistics."); -} - -ErrorOr root_session_id(Optional force_sid) -{ - auto stats = TRY(Core::ProcessStatisticsReader::get_all(false)); - - pid_t sid = (force_sid.has_value()) ? force_sid.value() : TRY(System::getsid()); - while (true) { - pid_t parent = TRY(get_proc(stats, sid))->ppid; - pid_t parent_sid = TRY(get_proc(stats, parent))->sid; - - if (parent_sid == 0) - break; - - sid = parent_sid; - } - - return sid; + return static_cast(rc); +#else + return 0; +#endif } ErrorOr logout(Optional force_sid)