sanebox: load the link cache from a static /etc path instead of via CLI args

This commit is contained in:
Colin 2024-05-15 23:55:15 +00:00
parent 348837ff4a
commit b4229ecb1e
3 changed files with 61 additions and 51 deletions

View File

@ -1,6 +1,18 @@
{ config, pkgs, ... }:
{ config, lib, pkgs, sane-lib, ... }:
let
cfg = config.sane.programs;
# create an AttrSet[String -> String]
# which maps symlink path -> symlink content
# for every symlink known to nix
fsSymlinksAsAttrs = lib.concatMapAttrs
(path: value: lib.optionalAttrs
((value.symlink or null) != null)
{
"${path}" = value.symlink.target;
}
)
config.sane.fs
;
in
{
sane.programs.sanebox = {
@ -16,4 +28,40 @@ in
sandbox.enable = false;
};
environment.etc = lib.mkIf cfg.sanebox.enabled {
"sanebox/symlink-cache".text = lib.concatStringsSep "\n" (
lib.mapAttrsToList
(k: v: "${k}\t${v}")
({
"/bin/sh" = config.environment.binsh;
"${builtins.unsafeDiscardStringContext config.environment.binsh}" = "bash";
"/usr/bin/env" = config.environment.usrbinenv;
"${builtins.unsafeDiscardStringContext config.environment.usrbinenv}" = "coreutils";
# "/run/current-system" = "${config.system.build.toplevel}";
# XXX: /run/current-system symlink can't be cached without forcing regular mass rebuilds:
# mount it as if it were a directory instead.
"/run/current-system" = "";
} // lib.optionalAttrs config.hardware.opengl.enable {
"/run/opengl-driver" = let
gl = config.hardware.opengl;
# from: <repo:nixos/nixpkgs:nixos/modules/hardware/opengl.nix>
package = pkgs.buildEnv {
name = "opengl-drivers";
paths = [ gl.package ] ++ gl.extraPackages;
};
in "${package}";
} // lib.optionalAttrs (config.hardware.opengl.enable && config.hardware.opengl.driSupport32Bit) {
"/run/opengl-driver-32" = let
gl = config.hardware.opengl;
# from: <repo:nixos/nixpkgs:nixos/modules/hardware/opengl.nix>
package = pkgs.buildEnv {
name = "opengl-drivers-32bit";
paths = [ gl.package32 ] ++ gl.extraPackages32;
};
in "${package}";
} // fsSymlinksAsAttrs)
);
};
}

View File

@ -43,24 +43,6 @@ let
makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { };
makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { sanebox = config.sane.programs.sanebox.package; };
# derefSymlinks: [ str ] -> [ str ]: for each path which is a symlink (or a child of a symlink'd dir), dereference one layer of symlink. else, return the path unchanged.
derefSymlinks = paths: builtins.map (fs-lib.derefSymlink config.sane.fs) paths;
# given some paths, walk all of these and keep only the paths/ancestors which are symlinks
keepOnlySymlinks = paths: lib.filter
(p: ((config.sane.fs."${builtins.unsafeDiscardStringContext p}" or {}).symlink or null) != null)
(lib.concatMap (p: path-lib.walk "/" p) paths)
;
# expandSymlinksOnce: [ str ] -> [ str ]
# dereference all the paths once, union with the original path set, and then filter out everything that's not a symlink.
expandSymlinksOnce = paths: keepOnlySymlinks (lib.unique (paths ++ derefSymlinks paths));
symlinksClosure = paths: lib.converge expandSymlinksOnce paths;
# symlinkToAttrs: [ str ] -> Attrs such that `attrs."${symlink}" = symlinkTarget`.
symlinksToAttrs = paths: lib.genAttrs
paths
(p: config.sane.fs."${p}".symlink.target)
;
vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn);
allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath ++ sandbox.extraHomePaths;
@ -98,37 +80,6 @@ let
userPathsClosure = lib.flatten (
builtins.map additionalPathsForUser (builtins.attrValues config.users.users)
);
symlinkCache = {
"/bin/sh" = config.environment.binsh;
"${builtins.unsafeDiscardStringContext config.environment.binsh}" = "bash";
"/usr/bin/env" = config.environment.usrbinenv;
"${builtins.unsafeDiscardStringContext config.environment.usrbinenv}" = "coreutils";
# "/run/current-system" = "${config.system.build.toplevel}";
# XXX: /run/current-system symlink can't be cached without forcing regular mass rebuilds:
# mount it as if it were a directory instead.
"/run/current-system" = "";
} // lib.optionalAttrs config.hardware.opengl.enable {
"/run/opengl-driver" = let
gl = config.hardware.opengl;
# from: <repo:nixos/nixpkgs:nixos/modules/hardware/opengl.nix>
package = pkgs.buildEnv {
name = "opengl-drivers";
paths = [ gl.package ] ++ gl.extraPackages;
};
in "${package}";
} // lib.optionalAttrs (config.hardware.opengl.enable && config.hardware.opengl.driSupport32Bit) {
"/run/opengl-driver-32" = let
gl = config.hardware.opengl;
# from: <repo:nixos/nixpkgs:nixos/modules/hardware/opengl.nix>
package = pkgs.buildEnv {
name = "opengl-drivers-32bit";
paths = [ gl.package32 ] ++ gl.extraPackages32;
};
in "${package}";
} // (
symlinksToAttrs (symlinksClosure (allowedPaths ++ userPathsClosure))
);
sandboxArgs = makeSandboxArgs {
inherit (sandbox)
@ -146,7 +97,7 @@ let
vpn.dns
else
null;
inherit allowedPaths allowedHomePaths allowedRunPaths symlinkCache;
inherit allowedPaths allowedHomePaths allowedRunPaths;
};
in
makeSandboxed {

View File

@ -804,6 +804,16 @@ noneGetCli() {
## ARGUMENT POST-PROCESSING
loadLinkCache() {
# readarray -t: reads some file into an array; each line becomes one element
readarray -t _linkCacheArray < /etc/sanebox/symlink-cache
for link in "${_linkCacheArray[@]}"; do
local from="${link%%\t*}"
local to="${link##*\t}"
linkCache["$from"]="$to"
done
}
### autodetect: if one of the CLI args looks like a path, that could be an input or output file
# so allow access to it.
maybeAutodetectPaths() {
@ -927,6 +937,7 @@ export SANEBOX_PREPEND="$SANEBOX_PREPEND"
export SANEBOX_APPEND="$SANEBOX_APPEND"
if [ -z "$isDisable" ]; then
loadLinkCache
# method-specific setup could add additional paths that need binding, so do that before canonicalization
"$method"Setup
maybeAutodetectPaths