wind+libui: Run wind as a separate user
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
apio 2023-11-22 21:29:59 +01:00
parent efeab5699e
commit 73a7d4f2a1
Signed by: apio
GPG Key ID: B8A7D06E42258954
8 changed files with 94 additions and 17 deletions

View File

@ -1,3 +1,4 @@
root:!:0:
users:!:1:
users:!:1:selene
wind:!:2:selene
selene:!:1000:

View File

@ -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

View File

@ -19,7 +19,7 @@ namespace os::SharedMemory
{
Result<u8*> 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<u8*> 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);

View File

@ -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;

View File

@ -8,6 +8,7 @@
*/
#include <luna/String.h>
#include <os/File.h>
#include <os/SharedMemory.h>
#include <sys/mman.h>
#include <ui/App.h>
@ -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;

View File

@ -5,6 +5,7 @@
#include <luna/String.h>
#include <os/File.h>
#include <os/SharedMemory.h>
#include <sys/mman.h>
#include <time.h>
#define TRY_OR_IPC_ERROR(expr) \
@ -94,10 +95,23 @@ static Result<void> 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<void> 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<void> 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);

View File

@ -16,6 +16,7 @@ struct Window : public LinkedListNode<Window>
ui::Rect contents;
u32* pixels;
String name;
String shm_path;
bool dirty { false };
Client* client;
int id;

View File

@ -6,6 +6,7 @@
#include "Screen.h"
#include "Window.h"
#include <errno.h>
#include <grp.h>
#include <moon/Keyboard.h>
#include <os/ArgumentParser.h>
#include <os/File.h>
@ -17,6 +18,7 @@
#include <string.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
@ -52,6 +54,31 @@ static void debug(const Vector<OwnedPtr<Client>>& clients)
os::println("--- wind: END DEBUG OUTPUT ---");
}
Result<void> set_supplementary_groups(const char* name)
{
Vector<gid_t> 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<int>(extra_groups.size()), extra_groups.data()) < 0) return err(errno);
return {};
}
Result<int> luna_main(int argc, char** argv)
{
srand((unsigned)time(NULL));
@ -95,25 +122,44 @@ Result<int> luna_main(int argc, char** argv)
close(fd);
}
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));
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);
}
}
if (setsid() < 0) perror("setsid");
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<StringView> { args, 2 }, false));
TRY(os::Process::exec("/usr/bin/init"_sv, Slice<StringView> { args, 2 }, false));
}
umask(0002);
setuid(2);
setgid(2);
ui::Color background = ui::Color::from_rgb(0x10, 0x10, 0x10);