modules/programs/sandbox: add an "embedProfile" option to source sandbox settings from the package instead of the system
This commit is contained in:
parent
79ee47bada
commit
a6b824d3c4
|
@ -43,7 +43,7 @@ let
|
|||
in
|
||||
makeSandboxed {
|
||||
inherit pkgName package;
|
||||
inherit (sandbox) binMap method extraConfig;
|
||||
inherit (sandbox) binMap embedProfile extraConfig method;
|
||||
vpn = if net == "vpn" then vpn else null;
|
||||
allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath ++ sandbox.extraHomePaths;
|
||||
allowedRootPaths = [
|
||||
|
@ -222,6 +222,17 @@ let
|
|||
how/whether to sandbox all binaries in the package.
|
||||
'';
|
||||
};
|
||||
sandbox.embedProfile = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
whether to embed the sandbox settings (path access, etc) into the wrapped binary that lives in /nix/store (true),
|
||||
or to encode only a profile name in the wrapper, and use it to query the settings at runtime (false).
|
||||
|
||||
embedded profile means you have to rebuild the wrapper any time you adjust the sandboxing flags,
|
||||
but it also means you can run the program without installing it: helpful for iteration.
|
||||
'';
|
||||
};
|
||||
sandbox.binMap = mkOption {
|
||||
type = types.attrsOf types.str;
|
||||
default = {};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
, sane-sandboxed
|
||||
, writeTextFile
|
||||
}:
|
||||
{ pkgName, package, method, vpn ? null, allowedHomePaths ? [], allowedRootPaths ? [], binMap ? {}, extraConfig ? [] }:
|
||||
{ pkgName, package, method, vpn ? null, allowedHomePaths ? [], allowedRootPaths ? [], binMap ? {}, extraConfig ? [], embedProfile ? false }:
|
||||
let
|
||||
sane-sandboxed' = sane-sandboxed.meta.mainProgram; #< load by bin name to reduce rebuilds
|
||||
|
||||
|
@ -34,6 +34,15 @@ let
|
|||
++ lib.optionals (vpn != null) vpnItems
|
||||
++ extraConfig;
|
||||
|
||||
sandboxProfilesPkg = writeTextFile {
|
||||
name = "${pkgName}-sandbox-profiles";
|
||||
destination = "/share/sane-sandboxed/profiles/${pkgName}.profile";
|
||||
text = builtins.concatStringsSep "\n" sandboxFlags;
|
||||
};
|
||||
sandboxProfileDir = "${sandboxProfilesPkg}/share/sane-sandboxed/profiles";
|
||||
|
||||
maybeEmbedProfilesDir = lib.optionalString embedProfile ''"--sane-sandbox-profile-dir" "${sandboxProfileDir}"'';
|
||||
|
||||
# two ways i could wrap a package in a sandbox:
|
||||
# 1. package.overrideAttrs, with `postFixup`.
|
||||
# 2. pkgs.symlinkJoin, or pkgs.runCommand, creating an entirely new package which calls into the inner binaries.
|
||||
|
@ -43,7 +52,7 @@ let
|
|||
# but even no.2 has to consider such edge-cases, just less frequently.
|
||||
# no.1 may bloat rebuild times.
|
||||
#
|
||||
# ultimately, no.1 is probably more reliable, but i expect i'll factor out a switch to allow either approach -- particularly when debugging package buld failures.
|
||||
# ultimately, no.1 is probably more reliable, but i expect i'll factor out a switch to allow either approach -- particularly when debugging package build failures.
|
||||
package' = if package.override.__functionArgs ? runCommand then
|
||||
package.override {
|
||||
runCommand = name: env: cmd: runCommand name env (cmd + lib.optionalString (name == package.name) ''
|
||||
|
@ -77,7 +86,7 @@ let
|
|||
|
||||
_profiles=("$_profileFromBinMap" "$_name" "${pkgName}" "${unwrapped.pname or ""}" "${unwrapped.name or ""}")
|
||||
# filter to just the unique profiles
|
||||
_profileArgs=()
|
||||
_profileArgs=(${maybeEmbedProfilesDir})
|
||||
for _profile in "''${_profiles[@]}"; do
|
||||
if [ -n "$_profile" ] && ! [[ " ''${_profileArgs[@]} " =~ " $_profile " ]]; then
|
||||
_profileArgs+=("--sane-sandbox-profile" "$_profile")
|
||||
|
@ -121,11 +130,7 @@ let
|
|||
test "$_numExec" -ne 0 && touch "$out"
|
||||
'';
|
||||
|
||||
sandboxProfiles = writeTextFile {
|
||||
name = "${pkgName}-sandbox-profiles";
|
||||
destination = "/share/sane-sandboxed/profiles/${pkgName}.profile";
|
||||
text = builtins.concatStringsSep "\n" sandboxFlags;
|
||||
};
|
||||
sandboxProfiles = sandboxProfilesPkg;
|
||||
};
|
||||
});
|
||||
in
|
||||
|
|
|
@ -4,6 +4,8 @@ isDebug="$SANE_SANDBOX_DEBUG"
|
|||
test -n "$isDebug" && set -x
|
||||
isDisable="$SANE_SANDBOX_DISABLE"
|
||||
|
||||
profileDirs=(@profileDirs@)
|
||||
|
||||
cliArgs=()
|
||||
cliPathArgs=()
|
||||
autodetect=
|
||||
|
@ -31,17 +33,25 @@ loadProfileByPath() {
|
|||
}
|
||||
|
||||
tryLoadProfileByName() {
|
||||
profilesNamed+=("$1")
|
||||
_profile="$1"
|
||||
if [ "${_profile:0:1}" = "/" ]; then
|
||||
# absolute path to profile.
|
||||
# consider it an error if it doesn't exist.
|
||||
# in general, prefer to use `--sane-sandbox-profile-dir` and specify the profile by name.
|
||||
# doing so maximizes compatibility with anything else that uses the name, like firejail.
|
||||
loadProfileByPath "$_profile"
|
||||
else
|
||||
profilesNamed+=("$_profile")
|
||||
|
||||
_profileDirs=(@profileDirs@)
|
||||
for _profileDir in "${_profileDirs[@]}"; do
|
||||
_profile="$_profileDir/$1.profile"
|
||||
debug "try profile at path: '$_profile'"
|
||||
if [ -f "$_profile" ]; then
|
||||
loadProfileByPath "$_profile"
|
||||
break
|
||||
fi
|
||||
done
|
||||
for _profileDir in "${profileDirs[@]}"; do
|
||||
_profilePath="$_profileDir/$_profile.profile"
|
||||
debug "try profile at path: '$_profilePath'"
|
||||
if [ -f "$_profilePath" ]; then
|
||||
loadProfileByPath "$_profilePath"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# convert e.g. `file:///Local%20Users/foo.mp3` to `file:///Local Users/foo.mp3`
|
||||
|
@ -160,6 +170,11 @@ parseArgs() {
|
|||
tryLoadProfileByName "$1"
|
||||
shift
|
||||
;;
|
||||
(--sane-sandbox-profile-dir)
|
||||
_dir="$1"
|
||||
shift
|
||||
profileDirs+=("$_dir")
|
||||
;;
|
||||
(*)
|
||||
parseArgsExtra+=("$_arg")
|
||||
;;
|
||||
|
|
Loading…
Reference in New Issue
Block a user