diff --git a/hosts/common/programs/mpv.nix b/hosts/common/programs/mpv.nix index 48336eed0..2a9f79d23 100644 --- a/hosts/common/programs/mpv.nix +++ b/hosts/common/programs/mpv.nix @@ -63,7 +63,9 @@ in }); sandbox.method = "bwrap"; - # sandbox.method = "firejail"; #< fails on moby + sandbox.extraConfig = [ + "--sane-sandbox-autodetect" + ]; persist.byStore.plaintext = [ ".local/state/mpv/watch_later" ]; fs.".config/mpv/input.conf".symlink.text = let diff --git a/modules/programs/default.nix b/modules/programs/default.nix index cb3ec285b..2c23cc3df 100644 --- a/modules/programs/default.nix +++ b/modules/programs/default.nix @@ -40,24 +40,12 @@ let let makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { sane-sandboxed = config.sane.sandboxHelper; }; vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn); - # TODO: restrict access to these media paths a bit more. - # maybe mount them user=nobody and restrict based on group? - mediaHomePaths = [ - "Books" - "Music" - "Pictures" - "Videos" - "tmp" - ]; - mediaRootPaths = [ - "/mnt/servo-media" - ]; in makeSandboxed { inherit pkgName package; inherit (sandbox) binMap method extraConfig; vpn = if net == "vpn" then vpn else null; - allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath ++ mediaHomePaths; + allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath; allowedRootPaths = [ "/nix/store" "/bin/sh" @@ -72,7 +60,7 @@ let "/run/user" #< particularly /run/user/$id/wayland-1, pulse, etc. "/run/secrets/home" # "/dev/dri" #< fix non-fatal "libEGL warning: wayland-egl: could not open /dev/dri/renderD128" (geary) - ] ++ mediaRootPaths ++ sandbox.extraPaths; + ] ++ sandbox.extraPaths; } ); pkgSpec = with lib; types.submodule ({ config, name, ... }: { diff --git a/modules/programs/sane-sandboxed b/modules/programs/sane-sandboxed index 0c40f0fc9..4ebab7838 100644 --- a/modules/programs/sane-sandboxed +++ b/modules/programs/sane-sandboxed @@ -3,6 +3,7 @@ test -n "$SANE_SANDBOX_DEBUG" && set -x cliArgs=() +autodetect= profilesNamed=() rootPaths=() homePaths=() @@ -67,21 +68,28 @@ parseArgs() { method="$1" shift ;; + (--sane-sandbox-autodetect) + # autodetect: crawl the CLI program's args & bind any which look like paths into the sandbox. + # this is handy for e.g. media players or document viewers. + # it's best combined with some two-tiered thing. + # e.g. first drop to the broadest path set of interest (Music,Videos,tmp, ...), then drop via autodetect. + autodetect=1 + ;; (--sane-sandbox-dns) # N.B.: these named temporary variables ensure that `set -x` causes $1 to be printed _dns="$1" - dns+=("$_dns") shift + dns+=("$_dns") ;; (--sane-sandbox-firejail-arg) _fjFlag="$1" - firejailFlags+=("$_fjFlag") shift + firejailFlags+=("$_fjFlag") ;; (--sane-sandbox-bwrap-arg) _bwrapFlag="$1" - bwrapFlags+=("$_bwrapFlag") shift + bwrapFlags+=("$_bwrapFlag") ;; (--sane-sandbox-net) net="$1" @@ -89,13 +97,13 @@ parseArgs() { ;; (--sane-sandbox-home-path) _path="$1" - homePaths+=("$_path") shift + homePaths+=("$_path") ;; (--sane-sandbox-path) _path="$1" - rootPaths+=("$_path") shift + rootPaths+=("$_path") ;; (--sane-sandbox-profile) tryLoadProfileByName "$1" @@ -175,7 +183,7 @@ bwrapIngestProfile() { # WIP bwrapExec() { - PATH="$PATH:@bubblewrap@/bin" exec bwrap --dev /dev --proc /proc "${bwrapFlags[@]}" -- "${cliArgs[@]}" + PATH="$PATH:@bubblewrap@/bin" exec bwrap --dev /dev --proc /proc --tmpfs /tmp "${bwrapFlags[@]}" -- "${cliArgs[@]}" } @@ -197,6 +205,17 @@ for _path in "${homePaths[@]}"; do "$method"IngestHomePath "$_path" done +if [ -n "$autodetect" ]; then + _pwd=$(pwd) + for _arg in "${cliArgs[@]}"; do + if [[ "$_arg" == "/*" ]]; then + test -e "$_arg" && "$method"IngestRootPath "$_arg" + elif test -e "$_pwd/$_arg"; then + "$method"IngestRootPath "$_pwd/$_arg" + fi + done +fi + if [ -n "$net" ]; then "$method"IngestNet "$net" fi