From f467ebc933f28b1bed3cc3a72b4945524308f801 Mon Sep 17 00:00:00 2001 From: Lucas CHOLLET Date: Thu, 9 Jun 2022 17:26:05 +0200 Subject: [PATCH] SystemServer: Detect spawning user for AcceptSocketConnections services SystemServer now invokes services with the same uid as the process that made the request. This allows the superuser to have a normal GUI workflow. For example, read and write its own files in TextEditor. --- Userland/Services/SystemServer/Service.cpp | 15 +++++++++++++++ Userland/Services/SystemServer/Service.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/Userland/Services/SystemServer/Service.cpp b/Userland/Services/SystemServer/Service.cpp index 6b93db32fc..babd700aa2 100644 --- a/Userland/Services/SystemServer/Service.cpp +++ b/Userland/Services/SystemServer/Service.cpp @@ -98,6 +98,8 @@ void Service::handle_socket_connection() } int accepted_fd = maybe_accepted_fd.release_value(); + // FIXME: Propagate errors + MUST(determine_account(accepted_fd)); spawn(accepted_fd); close(accepted_fd); } else { @@ -401,3 +403,16 @@ bool Service::is_enabled() const extern String g_system_mode; return m_system_modes.contains_slow(g_system_mode); } + +ErrorOr Service::determine_account(int fd) +{ + struct ucred creds = {}; + socklen_t creds_size = sizeof(creds); + TRY(Core::System::getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &creds, &creds_size)); + + auto const directory_name = String::formatted("/proc/{}/", creds.pid); + auto const stat = TRY(Core::System::stat(directory_name.characters())); + + m_account = TRY(Core::Account::from_uid(stat.st_uid)); + return {}; +} diff --git a/Userland/Services/SystemServer/Service.h b/Userland/Services/SystemServer/Service.h index 2f21ef6298..42920cf2c8 100644 --- a/Userland/Services/SystemServer/Service.h +++ b/Userland/Services/SystemServer/Service.h @@ -33,6 +33,8 @@ private: void spawn(int socket_fd = -1); + ErrorOr determine_account(int fd); + /// SocketDescriptor describes the details of a single socket that was /// requested by a service. struct SocketDescriptor {