LaunchServer+SystemServer: Move the portal to a user-specific directory

Various changes are needed to support this:
 - The directory is created by Core::Account on login (and located in
   /tmp).
 - Service's sockets are now deleted on exit (to allow re-creation)
 - SystemServer needs to handle SIGTERM to correctly destroy services.
This commit is contained in:
Lucas CHOLLET 2022-07-17 15:41:01 +02:00 committed by Linus Groh
parent cc0d53d6a6
commit 70846d701c
21 changed files with 47 additions and 26 deletions

View file

@ -71,13 +71,6 @@ Priority=low
KeepAlive=true
User=anon
[LaunchServer]
Socket=/tmp/portal/launch
SocketPermissions=600
Lazy=true
User=anon
SystemModes=text,graphical
[WindowServer]
Socket=/tmp/portal/window,/tmp/portal/wm
SocketPermissions=660

View file

@ -1,3 +1,9 @@
[LaunchServer]
Socket=/tmp/100/portal/launch
SocketPermissions=600
Lazy=true
SystemModes=text,graphical
[WorkspacePicker.Applet]
Priority=low
KeepAlive=true

View file

@ -34,7 +34,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/usr/share/man", "r"));
TRY(Core::System::unveil("/tmp/portal/filesystemaccess", "rw"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/portal/webcontent", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));

View file

@ -28,7 +28,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::unveil("/etc", "r"));
TRY(Core::System::unveil("/tmp/portal/webcontent", "rw"));
TRY(Core::System::unveil("/tmp/portal/lookup", "rw"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
TRY(Desktop::Launcher::add_allowed_url(URL::create_with_file_protocol("/bin/MailSettings")));

View file

@ -432,7 +432,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::unveil("/bin/TerminalSettings", "x"));
TRY(Core::System::unveil("/bin/utmpupdate", "x"));
TRY(Core::System::unveil("/etc/FileIconProvider.ini", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/portal/config", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));

View file

@ -32,7 +32,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
parser.parse(arguments);
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/portal/webcontent", "rw"));
TRY(Core::System::unveil("/tmp/portal/filesystemaccess", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));

View file

@ -38,7 +38,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
auto app = TRY(GUI::Application::try_create(arguments));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
if ((grid_rows > 0) ^ (grid_columns > 0)) {

View file

@ -45,7 +45,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
size_t board_size = Config::read_i32("2048"sv, ""sv, "board_size"sv, 4);

View file

@ -41,7 +41,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/bin/ChessEngine", "x"));
TRY(Core::System::unveil("/etc/passwd", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(Core::StandardPaths::home_directory(), "wcbr"sv));
TRY(Core::System::unveil(nullptr, nullptr));

View file

@ -31,7 +31,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
u32 high_score = Config::read_i32("FlappyBug"sv, "Game"sv, "HighScore"sv, 0);

View file

@ -37,7 +37,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-gameoflife"sv));

View file

@ -41,7 +41,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio recvfd sendfd rpath"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
auto window = TRY(GUI::Window::try_create());

View file

@ -33,7 +33,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-masterword"sv));

View file

@ -38,7 +38,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-minesweeper"sv));

View file

@ -34,7 +34,7 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
TRY(Core::System::pledge("stdio rpath recvfd sendfd"));
TRY(Core::System::unveil("/res", "r"));
TRY(Core::System::unveil("/tmp/portal/launch", "rw"));
TRY(Core::System::unveil("/tmp/100/portal/launch", "rw"));
TRY(Core::System::unveil(nullptr, nullptr));
auto app_icon = TRY(GUI::Icon::try_create_default_icon("app-snake"sv));

View file

@ -10,6 +10,7 @@
#include <AK/Random.h>
#include <AK/ScopeGuard.h>
#include <LibCore/Account.h>
#include <LibCore/Directory.h>
#include <LibCore/System.h>
#include <LibCore/UmaskScope.h>
#include <errno.h>
@ -150,6 +151,10 @@ bool Account::login() const
if (setuid(m_uid) < 0)
return false;
auto const temporary_directory = String::formatted("/tmp/{}", m_uid);
if (auto result = Core::Directory::create(temporary_directory, Core::Directory::CreateDirectories::No); result.is_error())
dbgln("{}", result.release_error());
return true;
}

View file

@ -36,7 +36,7 @@ auto Launcher::Details::from_details_str(String const& details_str) -> NonnullRe
class ConnectionToLaunchServer final
: public IPC::ConnectionToServer<LaunchClientEndpoint, LaunchServerEndpoint>
, public LaunchClientEndpoint {
IPC_CLIENT_CONNECTION(ConnectionToLaunchServer, "/tmp/portal/launch")
IPC_CLIENT_CONNECTION(ConnectionToLaunchServer, "/tmp/100/portal/launch")
private:
ConnectionToLaunchServer(NonnullOwnPtr<Core::Stream::LocalSocket> socket)
: IPC::ConnectionToServer<LaunchClientEndpoint, LaunchServerEndpoint>(*this, move(socket))

View file

@ -56,8 +56,9 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
{
auto app = TRY(GUI::Application::try_create(arguments));
TRY(Core::System::pledge("stdio recvfd sendfd rpath exec proc id"));
TRY(Core::System::pledge("stdio recvfd sendfd cpath rpath exec proc id"));
TRY(Core::System::unveil("/home", "r"));
TRY(Core::System::unveil("/tmp", "c"));
TRY(Core::System::unveil("/etc/passwd", "r"));
TRY(Core::System::unveil("/etc/shadow", "r"));
TRY(Core::System::unveil("/etc/group", "r"));

View file

@ -416,3 +416,11 @@ ErrorOr<void> Service::determine_account(int fd)
m_account = TRY(Core::Account::from_uid(stat.st_uid));
return {};
}
Service::~Service()
{
for (auto& socket : m_sockets) {
if (auto rc = remove(socket.path.characters()); rc != 0)
dbgln("{}", Error::from_errno(errno));
}
}

View file

@ -18,6 +18,7 @@ class Service final : public Core::Object {
public:
static ErrorOr<NonnullRefPtr<Service>> try_create(Core::ConfigFile const& config, StringView name);
~Service();
bool is_enabled() const;
void activate();

View file

@ -30,6 +30,13 @@
#include <unistd.h>
String g_system_mode = "graphical";
NonnullRefPtrVector<Service> g_services;
// NOTE: This handler ensures that the destructor of g_services is called.
static void sigterm_handler(int)
{
exit(0);
}
static void sigchld_handler(int)
{
@ -480,22 +487,22 @@ ErrorOr<int> serenity_main(Main::Arguments arguments)
Core::EventLoop event_loop;
event_loop.register_signal(SIGCHLD, sigchld_handler);
event_loop.register_signal(SIGTERM, sigterm_handler);
// Read our config and instantiate services.
// This takes care of setting up sockets.
NonnullRefPtrVector<Service> services;
auto config = (user)
? TRY(Core::ConfigFile::open_for_app("SystemServer"))
: TRY(Core::ConfigFile::open_for_system("SystemServer"));
for (auto const& name : config->groups()) {
auto service = TRY(Service::try_create(*config, name));
if (service->is_enabled())
services.append(service);
g_services.append(move(service));
}
// After we've set them all up, activate them!
dbgln("Activating {} services...", services.size());
for (auto& service : services)
dbgln("Activating {} services...", g_services.size());
for (auto& service : g_services)
service.activate();
return event_loop.exec();