programs: sandbox: omit media dirs by default, and implement --sane-sandbox-autodetect for programs which are liable to load data from paths

This commit is contained in:
2024-01-23 15:48:12 +00:00
parent 026f5dee4d
commit bfd5630e21
3 changed files with 30 additions and 21 deletions

View File

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

View File

@@ -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, ... }: {

View File

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