diff --git a/base/etc/group b/base/etc/group index 2fc04e87..e63c6746 100644 --- a/base/etc/group +++ b/base/etc/group @@ -1,4 +1,5 @@ root:!:0: users:!:1:selene wind:!:2:selene +wsys:!:3: selene:!:1000: diff --git a/wind/Client.h b/wind/Client.h index 435590cc..1d337589 100644 --- a/wind/Client.h +++ b/wind/Client.h @@ -6,12 +6,13 @@ struct Client { os::LocalServer::Client conn; Vector windows; + const bool privileged { false }; bool rpc_in_progress { false }; u8 rpc_id { 0 }; - Client(os::LocalServer::Client&& client) + Client(os::LocalServer::Client&& client, bool priv) #ifdef CLIENT_IMPLEMENTATION - : conn(move(client)), windows() {} + : conn(move(client)), windows(), privileged(priv) {} #else ; #endif diff --git a/wind/main.cpp b/wind/main.cpp index f5289011..d17775fc 100644 --- a/wind/main.cpp +++ b/wind/main.cpp @@ -6,17 +6,14 @@ #include "Screen.h" #include "Window.h" #include -#include #include #include #include #include #include #include -#include #include #include -#include #include #include #include @@ -24,6 +21,7 @@ static constexpr uid_t WIND_USER_ID = 2; static constexpr gid_t WIND_GROUP_ID = 2; +static constexpr gid_t WSYS_GROUP_ID = 3; static void debug(const Vector>& clients) { @@ -63,11 +61,14 @@ Result luna_main(int argc, char** argv) TRY(os::Security::pledge("stdio rpath wpath cpath unix proc exec tty id", NULL)); StringView socket_path = "/tmp/wind.sock"; + StringView system_socket_path = "/tmp/wsys.sock"; os::ArgumentParser parser; parser.add_description("The display server for Luna's graphical user interface."_sv); parser.add_system_program_info("wind"_sv); parser.add_value_argument(socket_path, 's', "socket"_sv, "the path for the local IPC socket"_sv); + parser.add_value_argument(system_socket_path, ' ', "system-socket"_sv, + "the path for the system IPC socket, for privileged clients"_sv); parser.parse(argc, argv); if (geteuid() != 0) @@ -90,10 +91,24 @@ Result luna_main(int argc, char** argv) Mouse mouse_pointer { screen.canvas() }; + umask(0002); + + // Set permissions to wind:wsys temporarily, to create /tmp/wsys.sock with those privileges. + setegid(WSYS_GROUP_ID); + seteuid(WIND_USER_ID); + + auto system_server = TRY(os::LocalServer::create(system_socket_path, false)); + TRY(system_server->listen(20)); + + seteuid(0); + // Opened all necessary files as root, drop privileges now. setgid(WIND_GROUP_ID); setuid(WIND_USER_ID); + auto server = TRY(os::LocalServer::create(socket_path, false)); + TRY(server->listen(20)); + int fd = open("/dev/null", O_RDONLY); if (fd >= 0) { @@ -101,11 +116,6 @@ Result luna_main(int argc, char** argv) close(fd); } - umask(0002); - - auto server = TRY(os::LocalServer::create(socket_path, false)); - TRY(server->listen(20)); - ui::Color background = ui::Color::from_rgb(0x10, 0x10, 0x10); Vector> clients; @@ -113,6 +123,7 @@ Result luna_main(int argc, char** argv) TRY(fds.try_append({ .fd = mouse->fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = keyboard->fd(), .events = POLLIN, .revents = 0 })); TRY(fds.try_append({ .fd = server->fd(), .events = POLLIN, .revents = 0 })); + TRY(fds.try_append({ .fd = system_server->fd(), .events = POLLIN, .revents = 0 })); TRY(os::Security::pledge("stdio rpath wpath cpath unix proc exec", NULL)); @@ -148,13 +159,29 @@ Result luna_main(int argc, char** argv) os::IPC::send_async(window->client->conn, request); } } + if (fds[2].revents & POLLIN) + { + auto client = TRY(server->accept()); + os::println("wind: New client connected!"); + TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 })); + OwnedPtr c = TRY(adopt_owned_if_nonnull(new Client(move(client), false))); + TRY(clients.try_append(move(c))); + } + if (fds[3].revents & POLLIN) + { + auto client = TRY(system_server->accept()); + os::println("wind: New privileged client connected!"); + TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 })); + OwnedPtr c = TRY(adopt_owned_if_nonnull(new Client(move(client), true))); + TRY(clients.try_append(move(c))); + } for (usize i = 0; i < clients.size(); i++) { - if (fds[i + 3].revents & POLLIN) wind::handle_ipc(*clients[i]); - if (fds[i + 3].revents & POLLHUP) + if (fds[i + 4].revents & POLLIN) wind::handle_ipc(*clients[i]); + if (fds[i + 4].revents & POLLHUP) { os::println("wind: Client %d disconnected", i); - fds.remove_at(i + 3); + fds.remove_at(i + 4); auto client = clients.remove_at(i); client->conn.disconnect(); for (auto& window : client->windows) @@ -168,13 +195,5 @@ Result luna_main(int argc, char** argv) } } } - if (fds[2].revents & POLLIN) - { - auto client = TRY(server->accept()); - os::println("wind: New client connected!"); - TRY(fds.try_append({ .fd = client.fd(), .events = POLLIN, .revents = 0 })); - OwnedPtr c = TRY(adopt_owned_if_nonnull(new Client(move(client)))); - TRY(clients.try_append(move(c))); - } } }