modules/programs: sandbox: allow method = "bunpen"

This commit is contained in:
2024-08-23 15:59:04 +00:00
parent abb19b1fc9
commit c86d893a2c
7 changed files with 51 additions and 11 deletions

View File

@@ -0,0 +1,19 @@
{ config, lib, pkgs, ... }:
let
cfg = config.sane.programs.bunpen;
in
{
sane.programs.bunpen = {
packageUnwrapped = pkgs.bunpen.overrideAttrs (base: {
# create a directory which holds just the `bunpen` so that we
# can add bunpen as a dependency to binaries via `PATH=/run/current-system/libexec/bunpen` without forcing rebuild every time bunpen changes
postInstall = ''
mkdir -p $out/libexec/bunpen
ln -s $out/bin/bunpen $out/libexec/bunpen/bunpen
'';
});
sandbox.enable = false;
};
environment.pathsToLink = lib.mkIf cfg.enabled [ "/libexec/bunpen" ];
}

View File

@@ -18,6 +18,7 @@
./brave.nix ./brave.nix
./brightnessctl.nix ./brightnessctl.nix
./bubblewrap.nix ./bubblewrap.nix
./bunpen.nix
./callaudiod.nix ./callaudiod.nix
./calls.nix ./calls.nix
./cantata.nix ./cantata.nix

View File

@@ -39,7 +39,6 @@ let
else else
let let
makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { }; makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { };
# makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { sanebox = config.sane.programs.sanebox.package; };
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { }; makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { };
vpn = if sandbox.net == "vpn" then vpn = if sandbox.net == "vpn" then
@@ -101,7 +100,13 @@ let
keepUsers = !sandbox.isolateUsers; keepUsers = !sandbox.isolateUsers;
}; };
in in
makeSandboxed { (makeSandboxed.override {
sanebox = if sandbox.method == "bunpen" then
pkgs.bunpen
else
pkgs.sanebox
;
}) {
inherit pkgName package; inherit pkgName package;
inherit (sandbox) inherit (sandbox)
embedSandboxer embedSandboxer
@@ -288,7 +293,7 @@ let
''; '';
}; };
sandbox.method = mkOption { sandbox.method = mkOption {
type = types.nullOr (types.enum [ "bwrap" "capshonly" "pastaonly" "landlock" ]); type = types.nullOr (types.enum [ "bunpen" "bwrap" "capshonly" "pastaonly" "landlock" ]);
default = null; #< TODO: default to something non-null default = null; #< TODO: default to something non-null
description = '' description = ''
how/whether to sandbox all binaries in the package. how/whether to sandbox all binaries in the package.
@@ -655,6 +660,7 @@ in
in lib.mkMerge [ in lib.mkMerge [
(take (sane-lib.mkTypedMerge take configs)) (take (sane-lib.mkTypedMerge take configs))
{ {
sane.programs.bunpen.enableFor.system = true;
sane.programs.sanebox.enableFor.system = true; sane.programs.sanebox.enableFor.system = true;
# expose the pkgs -- as available to the system -- as a build target. # expose the pkgs -- as available to the system -- as a build target.
system.build.pkgs = pkgs; system.build.pkgs = pkgs;

View File

@@ -31,7 +31,17 @@ let
usePortal = [ "--sanebox-portal" ]; usePortal = [ "--sanebox-portal" ];
whitelistPwd = [ "--sanebox-add-pwd" ]; whitelistPwd = [ "--sanebox-add-pwd" ];
}; };
gen = saneboxGenerators; bunpenGenerators = {
method = m: assert m == "bunpen"; [];
netDev = n: assert n == "all"; [ "--bunpen-keep-net" ];
path = p: [ "--bunpen-path" p ];
usePortal = []; #< TODO: the sandboxer really shouldn't have to know about portals.
};
gen = if method == "bunpen" then
bunpenGenerators
else
saneboxGenerators
;
allowPaths = flavor: paths: lib.flatten (builtins.map gen."path${flavor}" paths); allowPaths = flavor: paths: lib.flatten (builtins.map gen."path${flavor}" paths);
capabilityFlags = lib.flatten (builtins.map gen.capability capabilities); capabilityFlags = lib.flatten (builtins.map gen.capability capabilities);

View File

@@ -16,7 +16,7 @@
xorg, xorg,
}: }:
let let
fakeSaneSandboxed = writeShellScriptBin "sanebox" '' fakeSaneSandboxed = writeShellScriptBin sanebox.meta.mainProgram ''
# behave like the real sanebox with SANEBOX_DISABLE=1, # behave like the real sanebox with SANEBOX_DISABLE=1,
# but in a manner which avoids taking a dependency on the real sanebox. # but in a manner which avoids taking a dependency on the real sanebox.
# the primary use for this is to allow a package's `check` phase to work even when sanebox isn't available. # the primary use for this is to allow a package's `check` phase to work even when sanebox isn't available.
@@ -27,12 +27,12 @@ let
shift shift
done done
if [ "$#" -eq 0 ]; then if [ "$#" -eq 0 ]; then
>&2 echo "sanebox (mock): failed to parse args: ''${_origArgs[*]}" >&2 echo "${sanebox.meta.mainProgram} (mock): failed to parse args: ''${_origArgs[*]}"
exit 1 exit 1
fi fi
if [ -z "$SANEBOX_DISABLE" ]; then if [ -z "$SANEBOX_DISABLE" ]; then
>&2 echo "sanebox (mock): not called with SANEBOX_DISABLE=1; unsure how to sandbox: ''${_origArgs[*]}" >&2 echo "${sanebox.meta.mainProgram} (mock): not called with SANEBOX_DISABLE=1; unsure how to sandbox: ''${_origArgs[*]}"
exit 1 exit 1
fi fi
# assume that every argument after the binary name is an argument for the binary and not for the sandboxer. # assume that every argument after the binary name is an argument for the binary and not for the sandboxer.
@@ -101,13 +101,15 @@ let
else else
mv "$_dir/$_name" "$_dir/.sandboxed/" mv "$_dir/$_name" "$_dir/.sandboxed/"
fi fi
makeShellWrapper ${sanebox'} "$_dir/$_name" --suffix PATH : /run/current-system/sw/libexec/sanebox \ makeShellWrapper ${sanebox'} "$_dir/$_name" --suffix PATH : /run/current-system/sw/libexec/${sanebox.pname} \
${lib.escapeShellArgs (lib.flatten (builtins.map (f: [ "--add-flags" f ]) extraSandboxArgs))} \ ${lib.escapeShellArgs (lib.flatten (builtins.map (f: [ "--add-flags" f ]) extraSandboxArgs))} \
--add-flags "$_dir/.sandboxed/$_name" --add-flags "$_dir/.sandboxed/$_name"
# `exec`ing a script with an interpreter will smash $0. instead, source it to preserve $0: # `exec`ing a script with an interpreter will smash $0. instead, source it to preserve $0:
# - <https://github.com/NixOS/nixpkgs/issues/150841#issuecomment-995589961> # - <https://github.com/NixOS/nixpkgs/issues/150841#issuecomment-995589961>
substituteInPlace "$_dir/$_name" \ if [ -n "${sanebox.interpreter or ""}" ]; then
--replace-fail 'exec ' 'source ' substituteInPlace "$_dir/$_name" \
--replace-fail 'exec ' 'source '
fi
} }
derefWhileInSameOutput() { derefWhileInSameOutput() {
@@ -404,7 +406,7 @@ let
set -x set -x
local realbin="$(realpath $dir/$binname)" local realbin="$(realpath $dir/$binname)"
local interpreter=$(file "$realbin" | grep --only-matching "a /nix/.* script" | cut -d" " -f2 || echo "") local interpreter=$(file "$realbin" | grep --only-matching "a /nix/.* script" | cut -d" " -f2 || echo "")
${stdenv.hostPlatform.emulator buildPackages} $interpreter "$dir/$binname" --sanebox-net-dev all --sanebox-dns default --sanebox-net-gateway default --sanebox-replace-cli echo "printing for test" \ echo 'echo "printing for test"' | ${stdenv.hostPlatform.emulator buildPackages} $interpreter "$dir/$binname" --sanebox-net-dev all --sanebox-dns default --sanebox-net-gateway default --sanebox-replace-cli /bin/sh --bunpen-drop-shell \
| grep "printing for test" | grep "printing for test"
_numExec=$(( $_numExec + 1 )) _numExec=$(( $_numExec + 1 ))
} }

View File

@@ -17,5 +17,6 @@
run any executable in an isolated environment, run any executable in an isolated environment,
selectively exposing the specific resources (paths, IPC) it needs. selectively exposing the specific resources (paths, IPC) it needs.
''; '';
mainProgram = "bunpen";
}; };
} }

View File

@@ -45,6 +45,7 @@ stdenv.mkDerivation {
''; '';
passthru = { passthru = {
interpreter = lib.getBin bash;
runtimeDeps = [ runtimeDeps = [
bubblewrap bubblewrap
coreutils coreutils