modules/programs: sandbox: add enable flag and capabilities structured config

This commit is contained in:
2024-01-27 17:08:27 +00:00
parent 6c605944c5
commit 5ca208d07f
2 changed files with 19 additions and 4 deletions

View File

@@ -34,7 +34,7 @@ let
# wrap a package so that its binaries (maybe) run in a sandbox # wrap a package so that its binaries (maybe) run in a sandbox
wrapPkg = pkgName: { fs, net, persist, sandbox, ... }: package: ( wrapPkg = pkgName: { fs, net, persist, sandbox, ... }: package: (
if sandbox.method == null then if !sandbox.enable || sandbox.method == null then
package package
else else
let let
@@ -43,7 +43,7 @@ let
in in
makeSandboxed { makeSandboxed {
inherit pkgName package; inherit pkgName package;
inherit (sandbox) binMap embedProfile extraConfig method wrapperType; inherit (sandbox) binMap capabilities embedProfile extraConfig method wrapperType;
vpn = if net == "vpn" then vpn else null; vpn = if net == "vpn" then vpn else null;
allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath ++ sandbox.extraHomePaths; allowedHomePaths = builtins.attrNames fs ++ builtins.attrNames persist.byPath ++ sandbox.extraHomePaths;
allowedRootPaths = [ allowedRootPaths = [
@@ -222,6 +222,10 @@ let
how/whether to sandbox all binaries in the package. how/whether to sandbox all binaries in the package.
''; '';
}; };
sandbox.enable = mkOption {
type = types.bool;
default = true;
};
sandbox.embedProfile = mkOption { sandbox.embedProfile = mkOption {
type = types.bool; type = types.bool;
default = false; default = false;
@@ -258,6 +262,14 @@ let
then set `sandbox.binMap.umpv = "mpv";` to sandbox `bin/umpv` with the same rules as `bin/mpv` then set `sandbox.binMap.umpv = "mpv";` to sandbox `bin/umpv` with the same rules as `bin/mpv`
''; '';
}; };
sandbox.capabilities = mkOption {
type = types.listOf types.str;
default = [];
description = ''
list of Linux capabilities the program needs. lowercase, and without the cap_ prefix.
e.g. sandbox.capabilities = [ "net_admin" "net_raw" ];
'';
};
sandbox.extraPaths = mkOption { sandbox.extraPaths = mkOption {
type = types.listOf types.str; type = types.listOf types.str;
default = []; default = [];

View File

@@ -15,7 +15,7 @@ let
runHook postFixup runHook postFixup
''; '';
in in
{ pkgName, package, method, wrapperType, vpn ? null, allowedHomePaths ? [], allowedRootPaths ? [], binMap ? {}, extraConfig ? [], embedProfile ? false }: { pkgName, package, method, wrapperType, vpn ? null, allowedHomePaths ? [], allowedRootPaths ? [], binMap ? {}, capabilities ? [], extraConfig ? [], embedProfile ? false }:
let let
sane-sandboxed' = sane-sandboxed.meta.mainProgram; #< load by bin name to reduce rebuilds sane-sandboxed' = sane-sandboxed.meta.mainProgram; #< load by bin name to reduce rebuilds
@@ -30,6 +30,8 @@ let
allowPaths = paths: lib.flatten (builtins.map allowPath paths); allowPaths = paths: lib.flatten (builtins.map allowPath paths);
allowHomePaths = paths: lib.flatten (builtins.map allowHomePath paths); allowHomePaths = paths: lib.flatten (builtins.map allowHomePath paths);
capabilityFlags = lib.flatten (builtins.map (c: [ "--sane-sandbox-cap" c ]) capabilities);
vpnItems = [ vpnItems = [
"--sane-sandbox-net" "--sane-sandbox-net"
vpn.bridgeDevice vpn.bridgeDevice
@@ -42,6 +44,7 @@ let
"--sane-sandbox-method" method "--sane-sandbox-method" method
] ++ allowPaths allowedRootPaths ] ++ allowPaths allowedRootPaths
++ allowHomePaths allowedHomePaths ++ allowHomePaths allowedHomePaths
++ capabilityFlags
++ lib.optionals (vpn != null) vpnItems ++ lib.optionals (vpn != null) vpnItems
++ extraConfig; ++ extraConfig;
@@ -62,7 +65,7 @@ let
# note that no.2 ("wrappedDerivation") *doesn't support .desktop files yet*. # note that no.2 ("wrappedDerivation") *doesn't support .desktop files yet*.
# the final package simply doesn't include .desktop files, only bin/. # the final package simply doesn't include .desktop files, only bin/.
package' = if wrapperType == "inplace" then package' = if wrapperType == "inplace" then
if package.override.__functionArgs ? runCommand then if ((package.override or {}).__functionArgs or {}) ? runCommand then
package.override { package.override {
runCommand = name: env: cmd: runCommand name env (cmd + lib.optionalString (name == package.name) '' runCommand = name: env: cmd: runCommand name env (cmd + lib.optionalString (name == package.name) ''
# if the package is a runCommand (common for wrappers), then patch it to call our `postFixup` hook, first # if the package is a runCommand (common for wrappers), then patch it to call our `postFixup` hook, first