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
./brightnessctl.nix
./bubblewrap.nix
./bunpen.nix
./callaudiod.nix
./calls.nix
./cantata.nix

View File

@@ -39,7 +39,6 @@ let
else
let
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 { };
vpn = if sandbox.net == "vpn" then
@@ -101,7 +100,13 @@ let
keepUsers = !sandbox.isolateUsers;
};
in
makeSandboxed {
(makeSandboxed.override {
sanebox = if sandbox.method == "bunpen" then
pkgs.bunpen
else
pkgs.sanebox
;
}) {
inherit pkgName package;
inherit (sandbox)
embedSandboxer
@@ -288,7 +293,7 @@ let
'';
};
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
description = ''
how/whether to sandbox all binaries in the package.
@@ -655,6 +660,7 @@ in
in lib.mkMerge [
(take (sane-lib.mkTypedMerge take configs))
{
sane.programs.bunpen.enableFor.system = true;
sane.programs.sanebox.enableFor.system = true;
# expose the pkgs -- as available to the system -- as a build target.
system.build.pkgs = pkgs;

View File

@@ -31,7 +31,17 @@ let
usePortal = [ "--sanebox-portal" ];
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);
capabilityFlags = lib.flatten (builtins.map gen.capability capabilities);

View File

@@ -16,7 +16,7 @@
xorg,
}:
let
fakeSaneSandboxed = writeShellScriptBin "sanebox" ''
fakeSaneSandboxed = writeShellScriptBin sanebox.meta.mainProgram ''
# behave like the real sanebox with SANEBOX_DISABLE=1,
# 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.
@@ -27,12 +27,12 @@ let
shift
done
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
fi
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
fi
# 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
mv "$_dir/$_name" "$_dir/.sandboxed/"
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))} \
--add-flags "$_dir/.sandboxed/$_name"
# `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>
substituteInPlace "$_dir/$_name" \
--replace-fail 'exec ' 'source '
if [ -n "${sanebox.interpreter or ""}" ]; then
substituteInPlace "$_dir/$_name" \
--replace-fail 'exec ' 'source '
fi
}
derefWhileInSameOutput() {
@@ -404,7 +406,7 @@ let
set -x
local realbin="$(realpath $dir/$binname)"
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"
_numExec=$(( $_numExec + 1 ))
}

View File

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

View File

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