sway: patch to use a narrower sandbox

This commit is contained in:
Colin 2024-05-29 18:24:59 +00:00
parent 29bc1608aa
commit c5c174f988
3 changed files with 50 additions and 38 deletions

View File

@ -8,7 +8,7 @@
sandbox.extraHomePaths = [
".local/share/applications"
];
sandbox.extraRuntimePaths = [ "sway" ];
sandbox.extraRuntimePaths = [ "sway" ]; #< calls `swaymsg` to query rotation and see if there's room for a keyboard
suggestedPrograms = [
"gdbus"
"xdg-utils"

View File

@ -26,47 +26,59 @@ let
];
passthru.sway-unwrapped = configuredSway;
};
swayPackage = wrapSway (
pkgs.waylandPkgs.sway-unwrapped.override {
wlroots = (pkgs.waylandPkgs.wlroots.override {
# wlroots seems to launch Xwayland itself, and i can't easily just do that myself externally.
# so in order for the Xwayland it launches to be sandboxed, i need to patch the sandboxed version in here.
xwayland = config.sane.programs.xwayland.package;
}).overrideAttrs (upstream: {
# 2023/09/08: fix so clicking a notification can activate the corresponding window.
# - test: run dino, receive a message while tabbed away, click the desktop notification.
# - if sway activates the dino window (i.e. colors the workspace and tab), then all good
# - do all of this with only a touchscreen (e.g. on mobile phone) -- NOT a mouse/pointer
# 2023/12/17: this patch is still necessary
## what this patch does:
# - allows any wayland window to request activation, at any time.
# - traditionally, wayland only allows windows to request activation if
# the client requesting to transfer control has some connection to a recent user interaction.
# - e.g. the active window may transfer control to any window
# - a window which was very recently active may transfer control to itself
## alternative (longer-term) solutions:
# - fix this class of bug in gtk:
# - <https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/5782>
# - N.B.: this linked PR doesn't actually fix it
# - add xdg_activation_v1 support to SwayNC (my notification daemon):
# - <https://github.com/ErikReider/SwayNotificationCenter/issues/71>
# - mako notification daemon supports activation, can use as a reference
# - all of ~30 LoC, looks straight-forward
# - however, it's not clear that gtk4 (or dino) actually support this mode of activation.
# - i.e. my experience with dino is the same using mako as with SwayNC
postPatch = (upstream.postPatch or "") + ''
substituteInPlace types/wlr_xdg_activation_v1.c \
--replace-fail 'if (token->seat != NULL)' 'if (false && token->seat != NULL)'
'';
});
wlroots = (pkgs.waylandPkgs.wlroots.override {
# wlroots seems to launch Xwayland itself, and i can't easily just do that myself externally.
# so in order for the Xwayland it launches to be sandboxed, i need to patch the sandboxed version in here.
xwayland = config.sane.programs.xwayland.package;
}).overrideAttrs (upstream: {
# 2023/09/08: fix so clicking a notification can activate the corresponding window.
# - test: run dino, receive a message while tabbed away, click the desktop notification.
# - if sway activates the dino window (i.e. colors the workspace and tab), then all good
# - do all of this with only a touchscreen (e.g. on mobile phone) -- NOT a mouse/pointer
# 2023/12/17: this patch is still necessary
## what this patch does:
# - allows any wayland window to request activation, at any time.
# - traditionally, wayland only allows windows to request activation if
# the client requesting to transfer control has some connection to a recent user interaction.
# - e.g. the active window may transfer control to any window
# - a window which was very recently active may transfer control to itself
## alternative (longer-term) solutions:
# - fix this class of bug in gtk:
# - <https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/5782>
# - N.B.: this linked PR doesn't actually fix it
# - add xdg_activation_v1 support to SwayNC (my notification daemon):
# - <https://github.com/ErikReider/SwayNotificationCenter/issues/71>
# - mako notification daemon supports activation, can use as a reference
# - all of ~30 LoC, looks straight-forward
# - however, it's not clear that gtk4 (or dino) actually support this mode of activation.
# - i.e. my experience with dino is the same using mako as with SwayNC
postPatch = (upstream.postPatch or "") + ''
substituteInPlace types/wlr_xdg_activation_v1.c \
--replace-fail 'if (token->seat != NULL)' 'if (false && token->seat != NULL)'
'';
});
swayPackage = wrapSway (
(pkgs.waylandPkgs.sway-unwrapped.override {
inherit wlroots;
# about xwayland:
# - required by many electron apps, though some electron apps support NIXOS_OZONE_WL=1 for native wayland.
# - when xwayland is enabled, KOreader incorrectly chooses the X11 backend
# -> slower; blurrier
# - xwayland uses a small amount of memory (like 30MiB, IIRC?)
enableXWayland = config.sane.programs.xwayland.enabled;
}
}).overrideAttrs (upstream: {
# fix to create SWAYSOCK and WAYLAND_DISPLAY directly in a sandboxable subdirectory:
# i can't simply move it after creation i think because that would
# be an unsupported cross-device `mv`?
postPatch = (upstream.postPatch or "") + ''
substituteInPlace sway/ipc-server.c --replace-fail \
'"%s/sway-ipc.%u.%i.sock", dir, getuid(), getpid())' \
'"%s/sway/sway-ipc.sock", dir)'
substituteInPlace sway/server.c --replace-fail \
'"wayland-%u"' '"wl/wayland-%u"'
'';
})
);
in
{
@ -177,7 +189,7 @@ in
sandbox.whitelistDri = true;
sandbox.whitelistX = true; # sway invokes xwayland itself
sandbox.whitelistWayland = true;
sandbox.extraRuntimePaths = [ "/" ]; # TODO: should need just "sway". but even if i sandbox EVERY entry under run individually, it fails!
sandbox.extraRuntimePaths = [ "sway" ];
sandbox.extraPaths = [
# "/dev/input"
"/run/seatd.sock" #< required if not using `logind` systemd login manager
@ -222,7 +234,7 @@ in
env.DISPLAY = ":0";
# docs: <https://discourse.ubuntu.com/t/environment-variables-for-wayland-hackers/12750>
# N.B.: gtk apps support absolute paths for this; webkit apps (e.g. geary) support only relative paths (relative to $XDG_RUNTIME_DIR)
env.WAYLAND_DISPLAY = "wayland/wayland-1";
env.WAYLAND_DISPLAY = "wl/wayland-1";
services.sway = {
description = "sway: tiling wayland desktop environment";

View File

@ -464,7 +464,7 @@ let
sandbox.extraRuntimePaths =
lib.optionals config.sandbox.whitelistAudio [ "pipewire" "pulse" ] # this includes pipewire/pipewire-0-manager: is that ok?
++ lib.optionals (builtins.elem "user" config.sandbox.whitelistDbus) [ "bus" ]
++ lib.optionals config.sandbox.whitelistWayland [ "wayland" ] # app can still communicate with wayland server w/o this, if it has net access
++ lib.optionals config.sandbox.whitelistWayland [ "wl" ] # app can still communicate with wayland server w/o this, if it has net access
++ lib.optionals config.sandbox.whitelistS6 [ "s6" ] # TODO: this allows re-writing the services themselves: don't allow that!
;
sandbox.extraHomePaths = let