programs: sandboxing: make the profiles be generic across users

this is a step toward making the profile not even be dynamically loaded, since its content is no longer dynamic :)
This commit is contained in:
Colin 2024-05-15 08:33:29 +00:00
parent ea2653b7ce
commit b649071d98

View File

@ -63,22 +63,8 @@ let
vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn);
sandboxProfilesFor = userName: let
allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath ++ sandbox.extraHomePaths;
allowedRunPaths = sandbox.extraRuntimePaths;
homeDir = config.sane.users."${userName}".home;
uid = config.users.users."${userName}".uid;
xdgRuntimeDir = "/run/user/${builtins.toString uid}";
fullHomePaths = lib.optionals (userName != null) (
builtins.map
(p: path-lib.concat [ homeDir p ])
allowedHomePaths
);
fullRunPaths = lib.optionals (userName != null) (
builtins.map
(p: path-lib.concat [ xdgRuntimeDir p ])
allowedRunPaths
);
allowedPaths = [
"/nix/store"
"/bin/sh"
@ -95,25 +81,23 @@ let
] ++ lib.optionals (builtins.elem "system" sandbox.whitelistDbus) [ "/run/dbus/system_bus_socket" ]
++ sandbox.extraPaths
;
in makeProfile {
inherit pkgName;
inherit (sandbox)
autodetectCliPaths
capabilities
extraConfig
method
whitelistPwd
;
netDev = if sandbox.net == "vpn" then
vpn.bridgeDevice
else
sandbox.net;
dns = if sandbox.net == "vpn" then
vpn.dns
else
null;
inherit allowedPaths allowedHomePaths allowedRunPaths;
additionalPathsForUser = user: let
fullHomePaths = builtins.map
(p: path-lib.concat [ user.home p ])
allowedHomePaths
;
fullRunPaths = builtins.map
(p: path-lib.concat [ "/run/user/${builtins.toString user.uid}" p ])
allowedRunPaths
;
in
fullHomePaths ++ fullRunPaths;
# expand user-specific paths for all users.
# this feeds into the symlink cache, so that cached link data can be available no matter which user invokes the program.
userPathsClosure = lib.flatten (
builtins.map additionalPathsForUser (builtins.attrValues config.users.users)
);
symlinkCache = {
"/bin/sh" = config.environment.binsh;
"${builtins.unsafeDiscardStringContext config.environment.binsh}" = "bash";
@ -143,10 +127,28 @@ let
};
in "${package}";
} // (
symlinksToAttrs (symlinksClosure (allowedPaths ++ fullHomePaths ++ fullRunPaths))
symlinksToAttrs (symlinksClosure (allowedPaths ++ userPathsClosure))
);
sandboxProfiles = makeProfile {
inherit pkgName;
inherit (sandbox)
autodetectCliPaths
capabilities
extraConfig
method
whitelistPwd
;
netDev = if sandbox.net == "vpn" then
vpn.bridgeDevice
else
sandbox.net;
dns = if sandbox.net == "vpn" then
vpn.dns
else
null;
inherit allowedPaths allowedHomePaths allowedRunPaths symlinkCache;
};
defaultProfile = sandboxProfilesFor config.sane.defaultUser;
makeSandboxedArgs = {
inherit pkgName package;
inherit (sandbox)
@ -157,13 +159,13 @@ let
in
makeSandboxed (makeSandboxedArgs // {
passthru = {
inherit sandboxProfilesFor;
inherit sandboxProfiles;
withEmbeddedSandboxer = makeSandboxed (makeSandboxedArgs // {
# embed the sandboxer AND a profile, whichever profile the package would have if installed by the default user.
# useful to iterate a package's sandbox config without redeploying.
embedSandboxer = true;
extraSandboxerArgs = [
"--sanebox-profile-dir" "${defaultProfile}/share/sanebox/profiles"
"--sanebox-profile-dir" "${sandboxProfiles}/share/sanebox/profiles"
];
});
withEmbeddedSandboxerOnly = makeSandboxed (makeSandboxedArgs // {
@ -566,7 +568,7 @@ let
# conditionally add to system PATH and env
environment = lib.optionalAttrs (p.enabled && p.enableFor.system) {
systemPackages = lib.optionals (p.package != null) (
[ p.package ] ++ lib.optional (p.sandbox.enable && p.sandbox.method != null) (p.package.passthru.sandboxProfilesFor null)
[ p.package ] ++ lib.optional (p.sandbox.enable && p.sandbox.method != null) (p.package.passthru.sandboxProfiles)
);
# sessionVariables are set by PAM, as opposed to environment.variables which goes in /etc/profile
sessionVariables = p.env;
@ -575,7 +577,7 @@ let
# conditionally add to user(s) PATH
users.users = lib.mapAttrs (userName: en: {
packages = lib.optionals (p.package != null && en && p.enabled) (
[ p.package ] ++ lib.optional (p.sandbox.enable && p.sandbox.method != null) (p.package.passthru.sandboxProfilesFor userName)
[ p.package ] ++ lib.optional (p.sandbox.enable && p.sandbox.method != null) (p.package.passthru.sandboxProfiles)
);
}) p.enableFor.user;