From 61dbfeffe77df9c1a11413b3cb8954933e79b45f Mon Sep 17 00:00:00 2001 From: Ophestra Date: Tue, 25 Mar 2025 05:26:37 +0900 Subject: sandbox/wl: move into sandbox Signed-off-by: Ophestra --- wl/conn.go | 121 ------------------------------------------------------ wl/consts.go | 15 ------- wl/wayland-bind.c | 88 --------------------------------------- wl/wayland-bind.h | 3 -- wl/wl.go | 36 ---------------- 5 files changed, 263 deletions(-) delete mode 100644 wl/conn.go delete mode 100644 wl/consts.go delete mode 100644 wl/wayland-bind.c delete mode 100644 wl/wayland-bind.h delete mode 100644 wl/wl.go (limited to 'wl') diff --git a/wl/conn.go b/wl/conn.go deleted file mode 100644 index 9baa5abe..00000000 --- a/wl/conn.go +++ /dev/null @@ -1,121 +0,0 @@ -// Package wl implements Wayland security_context_v1 protocol. -package wl - -import ( - "errors" - "net" - "os" - "runtime" - "sync" - "syscall" -) - -type Conn struct { - conn *net.UnixConn - - done chan struct{} - doneOnce sync.Once - - mu sync.Mutex -} - -// Attach connects Conn to a wayland socket. -func (c *Conn) Attach(p string) (err error) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.conn != nil { - return errors.New("attached") - } - - c.conn, err = net.DialUnix("unix", nil, &net.UnixAddr{Name: p, Net: "unix"}) - return -} - -// Close releases resources and closes the connection to the wayland compositor. -func (c *Conn) Close() error { - c.mu.Lock() - defer c.mu.Unlock() - - if c.done == nil { - return errors.New("no socket bound") - } - - c.doneOnce.Do(func() { - c.done <- struct{}{} - <-c.done - }) - - // closed by wayland - runtime.SetFinalizer(c.conn, nil) - return nil -} - -func (c *Conn) Bind(p, appID, instanceID string) (*os.File, error) { - c.mu.Lock() - defer c.mu.Unlock() - - if c.conn == nil { - return nil, errors.New("not attached") - } - if c.done != nil { - return nil, errors.New("bound") - } - - if rc, err := c.conn.SyscallConn(); err != nil { - // unreachable - return nil, err - } else { - c.done = make(chan struct{}) - return bindRawConn(c.done, rc, p, appID, instanceID) - } -} - -func bindRawConn(done chan struct{}, rc syscall.RawConn, p, appID, instanceID string) (*os.File, error) { - var syncPipe [2]*os.File - - if r, w, err := os.Pipe(); err != nil { - return nil, err - } else { - syncPipe[0] = r - syncPipe[1] = w - } - - setupDone := make(chan error, 1) // does not block with c.done - - go func() { - if err := rc.Control(func(fd uintptr) { - // prevent runtime from closing the read end of sync fd - runtime.SetFinalizer(syncPipe[0], nil) - - // allow the Bind method to return after setup - setupDone <- bind(fd, p, appID, instanceID, syncPipe[0].Fd()) - close(setupDone) - - // keep socket alive until done is requested - <-done - runtime.KeepAlive(syncPipe[1]) - }); err != nil { - setupDone <- err - } - - // notify Close that rc.Control has returned - close(done) - }() - - // return write end of the pipe - return syncPipe[1], <-setupDone -} - -func bind(fd uintptr, p, appID, instanceID string, syncFd uintptr) error { - // ensure p is available - if f, err := os.Create(p); err != nil { - return err - } else if err = f.Close(); err != nil { - return err - } else if err = os.Remove(p); err != nil { - return err - } - - return bindWaylandFd(p, fd, appID, instanceID, syncFd) -} diff --git a/wl/consts.go b/wl/consts.go deleted file mode 100644 index 2ad4028c..00000000 --- a/wl/consts.go +++ /dev/null @@ -1,15 +0,0 @@ -package wl - -const ( - // WaylandDisplay contains the name of the server socket - // (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1147) - // which is concatenated with XDG_RUNTIME_DIR - // (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1171) - // or used as-is if absolute - // (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1176). - WaylandDisplay = "WAYLAND_DISPLAY" - - // FallbackName is used as the wayland socket name if WAYLAND_DISPLAY is unset - // (https://gitlab.freedesktop.org/wayland/wayland/-/blob/1.23.1/src/wayland-client.c#L1149). - FallbackName = "wayland-0" -) diff --git a/wl/wayland-bind.c b/wl/wayland-bind.c deleted file mode 100644 index 01e8b882..00000000 --- a/wl/wayland-bind.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "wayland-bind.h" -#include -#include -#include -#include -#include -#include - -#include -#include "security-context-v1-protocol.h" - -static void registry_handle_global(void *data, struct wl_registry *registry, uint32_t name, const char *interface, uint32_t version) { - struct wp_security_context_manager_v1 **out = data; - - if (strcmp(interface, wp_security_context_manager_v1_interface.name) == 0) - *out = wl_registry_bind(registry, name, &wp_security_context_manager_v1_interface, 1); -} - -static void registry_handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) { } // no-op - -static const struct wl_registry_listener registry_listener = { - .global = registry_handle_global, - .global_remove = registry_handle_global_remove, -}; - -int32_t f_bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd) { - int32_t res = 0; // refer to resErr for meaning - - struct wl_display *display; - display = wl_display_connect_to_fd(fd); - if (!display) { - res = 1; - goto out; - }; - - struct wl_registry *registry; - registry = wl_display_get_registry(display); - - struct wp_security_context_manager_v1 *security_context_manager = NULL; - wl_registry_add_listener(registry, ®istry_listener, &security_context_manager); - int ret; - ret = wl_display_roundtrip(display); - wl_registry_destroy(registry); - if (ret < 0) - goto out; - - if (!security_context_manager) { - res = 2; - goto out; - } - - int listen_fd = -1; - listen_fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (listen_fd < 0) - goto out; - - struct sockaddr_un sockaddr = {0}; - sockaddr.sun_family = AF_UNIX; - snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s", socket_path); - if (bind(listen_fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) != 0) - goto out; - - if (listen(listen_fd, 0) != 0) - goto out; - - struct wp_security_context_v1 *security_context; - security_context = wp_security_context_manager_v1_create_listener(security_context_manager, listen_fd, sync_fd); - wp_security_context_v1_set_sandbox_engine(security_context, "uk.gensokyo.fortify"); - wp_security_context_v1_set_app_id(security_context, app_id); - wp_security_context_v1_set_instance_id(security_context, instance_id); - wp_security_context_v1_commit(security_context); - wp_security_context_v1_destroy(security_context); - if (wl_display_roundtrip(display) < 0) - goto out; - -out: - if (listen_fd >= 0) - close(listen_fd); - if (security_context_manager) - wp_security_context_manager_v1_destroy(security_context_manager); - if (display) - wl_display_disconnect(display); - - free((void *)socket_path); - free((void *)app_id); - free((void *)instance_id); - return res; -} diff --git a/wl/wayland-bind.h b/wl/wayland-bind.h deleted file mode 100644 index 720dfe4e..00000000 --- a/wl/wayland-bind.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -int32_t f_bind_wayland_fd(char *socket_path, int fd, const char *app_id, const char *instance_id, int sync_fd); \ No newline at end of file diff --git a/wl/wl.go b/wl/wl.go deleted file mode 100644 index f75f063d..00000000 --- a/wl/wl.go +++ /dev/null @@ -1,36 +0,0 @@ -package wl - -//go:generate sh -c "wayland-scanner client-header `pkg-config --variable=datarootdir wayland-protocols`/wayland-protocols/staging/security-context/security-context-v1.xml security-context-v1-protocol.h" -//go:generate sh -c "wayland-scanner private-code `pkg-config --variable=datarootdir wayland-protocols`/wayland-protocols/staging/security-context/security-context-v1.xml security-context-v1-protocol.c" - -/* -#cgo linux pkg-config: --static wayland-client -#cgo freebsd openbsd LDFLAGS: -lwayland-client - -#include "wayland-bind.h" -*/ -import "C" -import ( - "errors" - "strings" -) - -var ( - ErrContainsNull = errors.New("string contains null character") -) - -var resErr = [...]error{ - 0: nil, - 1: errors.New("wl_display_connect_to_fd() failed"), - 2: errors.New("wp_security_context_v1 not available"), -} - -func bindWaylandFd(socketPath string, fd uintptr, appID, instanceID string, syncFd uintptr) error { - if hasNull(appID) || hasNull(instanceID) { - return ErrContainsNull - } - res := C.f_bind_wayland_fd(C.CString(socketPath), C.int(fd), C.CString(appID), C.CString(instanceID), C.int(syncFd)) - return resErr[int32(res)] -} - -func hasNull(s string) bool { return strings.IndexByte(s, '\x00') > -1 } -- cgit v1.3.1