From 73a7d4f2a1f9d46c35b186cd07bbc5e8e5170c4b Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 22 Nov 2023 21:29:59 +0100 Subject: [PATCH] wind+libui: Run wind as a separate user --- base/etc/group | 3 +- base/etc/passwd | 1 + libos/src/SharedMemory.cpp | 4 +- libui/include/ui/ipc/Server.h | 8 ++++ libui/src/Window.cpp | 7 +++- wind/IPC.cpp | 15 ++++++++ wind/Window.h | 1 + wind/main.cpp | 72 ++++++++++++++++++++++++++++------- 8 files changed, 94 insertions(+), 17 deletions(-) diff --git a/base/etc/group b/base/etc/group index 59582096..2fc04e87 100644 --- a/base/etc/group +++ b/base/etc/group @@ -1,3 +1,4 @@ root:!:0: -users:!:1: +users:!:1:selene +wind:!:2:selene selene:!:1000: diff --git a/base/etc/passwd b/base/etc/passwd index 2eb5fd77..65dab9f1 100644 --- a/base/etc/passwd +++ b/base/etc/passwd @@ -1,2 +1,3 @@ root:toor:0:0:Administrator:/:/usr/bin/sh +wind:!:2:2:Window Manager:/:/usr/bin/init selene:moon:1000:1000:User:/home/selene:/usr/bin/sh diff --git a/libos/src/SharedMemory.cpp b/libos/src/SharedMemory.cpp index 743567f7..a2c1405b 100644 --- a/libos/src/SharedMemory.cpp +++ b/libos/src/SharedMemory.cpp @@ -19,7 +19,7 @@ namespace os::SharedMemory { Result create(StringView path, usize size) { - int fd = shm_open(path.chars(), O_RDWR | O_CREAT | O_EXCL, 0600); + int fd = shm_open(path.chars(), O_RDWR | O_CREAT | O_EXCL, 0660); if (fd < 0) { int olderr = errno; @@ -57,7 +57,7 @@ namespace os::SharedMemory Result adopt(StringView path, usize size, bool delete_fs) { - int fd = shm_open(path.chars(), O_RDWR, 0600); + int fd = shm_open(path.chars(), O_RDWR, 0660); if (delete_fs) shm_unlink(path.chars()); if (fd < 0) return err(errno); diff --git a/libui/include/ui/ipc/Server.h b/libui/include/ui/ipc/Server.h index dac9cd21..6eca6461 100644 --- a/libui/include/ui/ipc/Server.h +++ b/libui/include/ui/ipc/Server.h @@ -19,6 +19,7 @@ namespace ui { IPC_ENUM_SERVER(ui), CREATE_WINDOW_ID, + REMOVE_SHM_ID, SET_WINDOW_TITLE_ID, INVALIDATE_ID, CLOSE_WINDOW_ID, @@ -41,6 +42,13 @@ namespace ui WindowType type; }; + struct RemoveSharedMemoryRequest + { + static constexpr u8 ID = REMOVE_SHM_ID; + + int window; + }; + struct SetWindowTitleRequest { static constexpr u8 ID = SET_WINDOW_TITLE_ID; diff --git a/libui/src/Window.cpp b/libui/src/Window.cpp index 0acb267d..21b88af6 100644 --- a/libui/src/Window.cpp +++ b/libui/src/Window.cpp @@ -8,6 +8,7 @@ */ #include +#include #include #include #include @@ -27,13 +28,17 @@ namespace ui auto path = COPY_IPC_STRING(response.shm_path); - u32* pixels = (u32*)TRY(os::SharedMemory::adopt(path.view(), rect.height * rect.width * 4)); + u32* pixels = (u32*)TRY(os::SharedMemory::adopt(path.view(), rect.height * rect.width * 4, false)); window->m_canvas = ui::Canvas { rect.width, rect.height, rect.width, (u8*)pixels }; window->m_id = response.window; Window* p = window.ptr(); + ui::RemoveSharedMemoryRequest shm_request; + shm_request.window = response.window; + os::IPC::send_async(App::the().client(), shm_request); + App::the().register_window(move(window), {}); return p; diff --git a/wind/IPC.cpp b/wind/IPC.cpp index fe73a5dc..7b2222c7 100644 --- a/wind/IPC.cpp +++ b/wind/IPC.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #define TRY_OR_IPC_ERROR(expr) \ @@ -94,10 +95,23 @@ static Result handle_create_window_message(Client& client) ui::CreateWindowResponse response; response.window = id; SET_IPC_STRING(response.shm_path, shm_path.chars()); + window->shm_path = move(shm_path); os::IPC::send_async(client.conn, response); return {}; } +static Result handle_remove_shm_message(Client& client) +{ + ui::RemoveSharedMemoryRequest request; + READ_MESSAGE(request); + + CHECK_WINDOW_ID(request); + + shm_unlink(client.windows[request.window]->shm_path.chars()); + + return {}; +} + static Result handle_set_window_title_message(Client& client) { ui::SetWindowTitleRequest request; @@ -162,6 +176,7 @@ namespace wind switch (id) { case ui::CREATE_WINDOW_ID: return handle_create_window_message(client); + case ui::REMOVE_SHM_ID: return handle_remove_shm_message(client); case ui::SET_WINDOW_TITLE_ID: return handle_set_window_title_message(client); case ui::INVALIDATE_ID: return handle_invalidate_message(client); case ui::CLOSE_WINDOW_ID: return handle_close_window_message(client); diff --git a/wind/Window.h b/wind/Window.h index f87d5526..c2859047 100644 --- a/wind/Window.h +++ b/wind/Window.h @@ -16,6 +16,7 @@ struct Window : public LinkedListNode ui::Rect contents; u32* pixels; String name; + String shm_path; bool dirty { false }; Client* client; int id; diff --git a/wind/main.cpp b/wind/main.cpp index 0b4718d3..a291db53 100644 --- a/wind/main.cpp +++ b/wind/main.cpp @@ -6,6 +6,7 @@ #include "Screen.h" #include "Window.h" #include +#include #include #include #include @@ -17,6 +18,7 @@ #include #include #include +#include #include #include @@ -52,6 +54,31 @@ static void debug(const Vector>& clients) os::println("--- wind: END DEBUG OUTPUT ---"); } +Result set_supplementary_groups(const char* name) +{ + Vector extra_groups; + + setgrent(); + group* grp; + while ((grp = getgrent())) + { + for (char** user = grp->gr_mem; *user; user++) + { + if (!strcmp(*user, name)) + { + os::println("Adding supplementary group: %d", grp->gr_gid); + TRY(extra_groups.try_append(grp->gr_gid)); + break; + } + } + } + endgrent(); + + if (setgroups(static_cast(extra_groups.size()), extra_groups.data()) < 0) return err(errno); + + return {}; +} + Result luna_main(int argc, char** argv) { srand((unsigned)time(NULL)); @@ -95,25 +122,44 @@ Result luna_main(int argc, char** argv) close(fd); } - clearenv(); - - if (!user.is_empty()) - { - auto* pwd = getpwnam(user.chars()); - if (pwd) - { - setgid(pwd->pw_gid); - setuid(pwd->pw_uid); - } - } + setegid(2); + seteuid(2); if (setsid() < 0) perror("setsid"); + mode_t mask = umask(0002); + auto server = TRY(os::LocalServer::create(socket_path, false)); TRY(server->listen(20)); - StringView args[] = { "/usr/bin/init"_sv, "--user"_sv }; - TRY(os::Process::spawn("/usr/bin/init"_sv, Slice { args, 2 }, false)); + umask(mask); + + seteuid(0); + + clearenv(); + + pid_t child = TRY(os::Process::fork()); + if (!child) + { + if (!user.is_empty()) + { + auto* pwd = getpwnam(user.chars()); + if (pwd) + { + TRY(set_supplementary_groups(user.chars())); + setgid(pwd->pw_gid); + setuid(pwd->pw_uid); + } + } + + StringView args[] = { "/usr/bin/init"_sv, "--user"_sv }; + TRY(os::Process::exec("/usr/bin/init"_sv, Slice { args, 2 }, false)); + } + + umask(0002); + + setuid(2); + setgid(2); ui::Color background = ui::Color::from_rgb(0x10, 0x10, 0x10);