From 5205251f6fc3ceb8695f1a842ddef2c6869a30b9 Mon Sep 17 00:00:00 2001 From: Colin Date: Sat, 23 Mar 2024 15:33:23 +0000 Subject: [PATCH] programs: xwayland: sandbox it without exposing net access --- hosts/common/polyunfill.nix | 5 +++++ hosts/common/programs/assorted.nix | 4 ++-- hosts/common/programs/element-desktop.nix | 1 + hosts/common/programs/sway/default.nix | 11 ++++++++--- modules/programs/default.nix | 19 +++++++++++-------- 5 files changed, 27 insertions(+), 13 deletions(-) diff --git a/hosts/common/polyunfill.nix b/hosts/common/polyunfill.nix index b566efc5..3da348d8 100644 --- a/hosts/common/polyunfill.nix +++ b/hosts/common/polyunfill.nix @@ -64,4 +64,9 @@ # pkgs.udisks # pkgs.wpa_supplicant ]; + + # systemd by default forces shitty defaults for e.g. /tmp/.X11-unix. + # nixos propagates those in: + # by overwriting this with an empty file, we can effectively remove it. + environment.etc."tmpfiles.d/x11.conf".text = "# (removed by Colin)"; } diff --git a/hosts/common/programs/assorted.nix b/hosts/common/programs/assorted.nix index 3880b752..f46b75ce 100644 --- a/hosts/common/programs/assorted.nix +++ b/hosts/common/programs/assorted.nix @@ -401,7 +401,7 @@ in gh.persist.byStore.private = [ ".config/gh" ]; gimp.sandbox.method = "bwrap"; - gimp.sandbox.net = "clearnet"; #< for Xwayland + gimp.sandbox.whitelistX = true; gimp.sandbox.whitelistWayland = true; gimp.sandbox.extraHomePaths = [ "Pictures/albums" @@ -931,7 +931,7 @@ in xwayland.sandbox.method = "bwrap"; xwayland.sandbox.wrapperType = "inplace"; #< consumers use it as a library (e.g. wlroots) xwayland.sandbox.whitelistWayland = true; #< just assuming this is needed - xwayland.sandbox.net = "clearnet"; #< just assuming this is needed (X11 traffic) + xwayland.sandbox.whitelistX = true; xwayland.sandbox.whitelistDri = true; #< would assume this gives better gfx perf xterm.sandbox.enable = false; # need to be able to do everything diff --git a/hosts/common/programs/element-desktop.nix b/hosts/common/programs/element-desktop.nix index f2c4b99c..002d92e5 100644 --- a/hosts/common/programs/element-desktop.nix +++ b/hosts/common/programs/element-desktop.nix @@ -22,6 +22,7 @@ sandbox.whitelistDbus = [ "user" ]; # notifications sandbox.whitelistDri = true; sandbox.whitelistWayland = true; + sandbox.whitelistX = true; sandbox.extraHomePaths = [ "Music" "Pictures/albums" diff --git a/hosts/common/programs/sway/default.nix b/hosts/common/programs/sway/default.nix index 5cadca5b..f67a0bcf 100644 --- a/hosts/common/programs/sway/default.nix +++ b/hosts/common/programs/sway/default.nix @@ -6,7 +6,6 @@ let cfg = config.sane.programs.sway; wrapSway = configuredSway: let swayLauncher = pkgs.writeShellScriptBin "sway" '' - mkdir -p "$(dirname "$SWAYSOCK")" # delete DISPLAY-related vars from env before launch, else sway will try to connect to a remote display. # (consider: nested sway sessions, where sway actually has a reason to read these) exec env -u DISPLAY -u WAYLAND_DISPLAY ${configuredSway}/bin/sway 2>&1 @@ -165,10 +164,10 @@ in sandbox.method = "bwrap"; sandbox.wrapperType = "inplace"; - sandbox.net = "clearnet"; #< for Xwayland (TODO: separate!) sandbox.whitelistAudio = true; # it runs playerctl directly sandbox.whitelistDbus = [ "system" "user" ]; # to e.g. launch apps sandbox.whitelistDri = true; + sandbox.whitelistX = true; # sway invokes xwayland itself sandbox.whitelistWayland = true; # needs to *create* the sway socket. could move the sway socket into its own directory, and whitelist just that, but doesn't buy me much. sandbox.extraRuntimePaths = [ "/" ]; @@ -218,12 +217,18 @@ in env.SWAYSOCK = "$XDG_RUNTIME_DIR/sway/sway-ipc.sock"; # TODO: ensure this is reliable? might not work across sway restarts, etc. env.DISPLAY = ":0"; + # docs: env.WAYLAND_DISPLAY = "wayland-1"; services.sway = { description = "sway: tiling wayland desktop environment"; dependencyOf = [ "graphical-session" ]; - command = "sway"; + command = pkgs.writeShellScript "sway-start" '' + # have to create these directories before launching sway so that they're available in the sandbox + mkdir -p "$(dirname "$SWAYSOCK")" + mkdir -p /tmp/.X11-unix # for Xwayland + exec sway + ''; readiness.waitExists = "$SWAY_SOCK"; }; # link the graphical-session into the default target, so sway gets auto-started diff --git a/modules/programs/default.nix b/modules/programs/default.nix index 923cfc0f..d00aa123 100644 --- a/modules/programs/default.nix +++ b/modules/programs/default.nix @@ -479,14 +479,17 @@ let # this gets the symlink into the sandbox, but not the actual secret. fs = lib.mapAttrs (_homePath: _secretSrc: {}) config.secrets; - sandbox.net = lib.mkIf config.sandbox.whitelistX "localhost"; - - sandbox.extraPaths = lib.mkIf config.sandbox.whitelistDri [ - # /dev/dri/renderD128: requested by wayland-egl (e.g. KOreader, animatch, geary) - # - but everything seems to gracefully fallback to *something* (MESA software rendering?) - # - CPU usage difference between playing videos in Gtk apps (e.g. fractal) with v.s. without DRI is 10% v.s. 90%. - # - GPU attack surface is *large*: - "/dev/dri" "/sys/dev/char" "/sys/devices" # (lappy: "/sys/devices/pci0000:00", moby needs something different) + sandbox.extraPaths = lib.mkMerge [ + (lib.mkIf config.sandbox.whitelistDri [ + # /dev/dri/renderD128: requested by wayland-egl (e.g. KOreader, animatch, geary) + # - but everything seems to gracefully fallback to *something* (MESA software rendering?) + # - CPU usage difference between playing videos in Gtk apps (e.g. fractal) with v.s. without DRI is 10% v.s. 90%. + # - GPU attack surface is *large*: + "/dev/dri" "/sys/dev/char" "/sys/devices" # (lappy: "/sys/devices/pci0000:00", moby needs something different) + ]) + (lib.mkIf config.sandbox.whitelistX [ + "/tmp/.X11-unix" + ]) ]; sandbox.extraConfig = lib.mkIf config.sandbox.usePortal [ "--sane-sandbox-portal"