diff --git a/modules/lib/merge.nix b/modules/lib/merge.nix index bc19bc5bf..061dde66e 100644 --- a/modules/lib/merge.nix +++ b/modules/lib/merge.nix @@ -62,14 +62,13 @@ rec { # now items is a list where every element is undecorated at the toplevel. # e.g. each item is an ordinary attrset or primitive. # we still need to discharge the *rest* of the path though, for every item. - name = lib.head path; - downstream = lib.tail path; - dischargeDownstream = it: if path != [] && it ? name then - builtins.map (v: it // { "${name}" = v; }) (dischargeToPath downstream it."${name}") - else - [ it ]; in - lib.concatMap dischargeDownstream items; + lib.concatMap (dischargeDownstream path) items; + + dischargeDownstream = path: it: if path != [] && it ? name then + builtins.map (v: it // { "${lib.head path}" = v; }) (dischargeToPath (lib.tail path) it."${lib.head path}") + else + [ it ]; # discharge many items but only over one path. # Type: dischargeItemsToPaths :: [Attrs] -> String -> [Attrs] @@ -92,9 +91,10 @@ rec { # since the act of discharging should have forced all the relevant data out to the leaves, # we just set each expected terminal to null (initializing the parents when necessary) # and that gives a standard value for any fully-consumed items that we can do equality comparisons with. - wipePath = acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path null); - remainder = builtins.foldl' wipePath i paths; - expected-remainder = builtins.foldl' wipePath {} paths; + remainder = builtins.foldl' _wipePath i paths; + expected-remainder = builtins.foldl' _wipePath {} paths; in assert remainder == expected-remainder; true; + + _wipePath = acc: path: lib.recursiveUpdate acc (lib.setAttrByPath path null); } diff --git a/modules/persist/default.nix b/modules/persist/default.nix index 2e945418e..ba31c4bc3 100644 --- a/modules/persist/default.nix +++ b/modules/persist/default.nix @@ -118,6 +118,19 @@ let } ]; + # set the `store` attribute on one dir attrset + annotateWithStore = store: dir: { + "${dir.path}".store = store; + }; + # convert an `entryInStore` to an `entryAtPath` (less the `store` item) + dirToAttrs = dir: { + "${dir.path}" = builtins.removeAttrs dir ["path"]; + }; + # AttrSet -> (store -> path -> AttrSet) -> [AttrSet] + applyToAllStores = byStore: f: lib.concatMap + (store: map (f store) byStore."${store}") + (builtins.attrNames byStore); + # this submodule converts store-based access to path-based access so that the user can specify e.g.: # .byStore.private = [ ".cache/vim" ]; # .byStore.private = [ { path=".cache/vim"; mode = "0700"; } ]; @@ -140,29 +153,12 @@ let ''; }; }; - config = let - # set the `store` attribute on one dir attrset - annotateWithStore = store: dir: { - "${dir.path}".store = store; - }; - # convert an `entryInStore` to an `entryAtPath` (less the `store` item) - dirToAttrs = dir: { - "${dir.path}" = builtins.removeAttrs dir ["path"]; - }; - # store-names = attrNames cfg.stores; - # :: (store -> entry -> AttrSet) -> [AttrSet] - # applyToAllStores = f: lib.concatMap - # (store: map (f store) config.byStore."${store}") - # store-names; - applyToAllStores = f: lib.concatMap - (store: map (f store) config.byStore."${store}") - (builtins.attrNames config.byStore); - in { + config = { byPath = lib.mkMerge (concatLists [ # convert the list-style per-store entries into attrsOf entries - (applyToAllStores (_store: dirToAttrs)) + (applyToAllStores config.byStore (_store: dirToAttrs)) # add the `store` attr to everything we ingested - (applyToAllStores annotateWithStore) + (applyToAllStores config.byStore annotateWithStore) ]); }; }); diff --git a/modules/programs/default.nix b/modules/programs/default.nix index ea9f06a72..030f4e491 100644 --- a/modules/programs/default.nix +++ b/modules/programs/default.nix @@ -3,6 +3,9 @@ let saneCfg = config.sane; cfg = config.sane.programs; + makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { }; + makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { }; + # create a map: # { # "${pkgName}" = { @@ -38,9 +41,6 @@ let package else let - makeSandboxArgs = pkgs.callPackage ./make-sandbox-args.nix { }; - makeSandboxed = pkgs.callPackage ./make-sandboxed.nix { }; - vpn = if sandbox.net == "vpn" then lib.findSingle (v: v.isDefault) null null (builtins.attrValues config.sane.vpn) else if sandbox.net == "vpn.wg-home" then diff --git a/modules/programs/make-sandbox-args.nix b/modules/programs/make-sandbox-args.nix index 2091966a0..f9f5426d2 100644 --- a/modules/programs/make-sandbox-args.nix +++ b/modules/programs/make-sandbox-args.nix @@ -1,20 +1,4 @@ { lib }: -{ - method, - allowedPaths ? [], - allowedHomePaths ? [], - allowedRunPaths ? [], - autodetectCliPaths ? false, - capabilities ? [], - dns ? null, - keepIpc ? false, - keepPids ? false, - tryKeepUsers ? false, - netDev ? null, - netGateway ? null, - whitelistPwd ? false, - extraConfig ? [], -}: let saneboxGenerators = { autodetectCliPaths = style: [ "--sanebox-autodetect" style ]; @@ -26,9 +10,9 @@ let method = method: [ "--sanebox-method" method ]; netDev = netDev: [ "--sanebox-net-dev" netDev ]; netGateway = netGateway: [ "--sanebox-net-gateway" netGateway ]; - path = p: [ "--sanebox-path" p ]; - path-home = p: [ "--sanebox-home-path" p ]; - path-run = p: [ "--sanebox-run-path" p ]; + path.unqualified = p: [ "--sanebox-path" p ]; + path.home = p: [ "--sanebox-home-path" p ]; + path.run = p: [ "--sanebox-run-path" p ]; whitelistPwd = [ "--sanebox-add-pwd" ]; }; bunpenGenerators = { @@ -61,32 +45,50 @@ let else [ "--bunpen-path" "/dev/net/tun" "--bunpen-net-dev" n ]; netGateway = netGateway: [ "--bunpen-net-gateway" netGateway ]; - path = p: [ "--bunpen-path" p ]; - path-home = p: [ "--bunpen-home-path" p ]; - path-run = p: [ "--bunpen-run-path" p ]; + path.unqualified = p: [ "--bunpen-path" p ]; + path.home = p: [ "--bunpen-home-path" p ]; + path.run = p: [ "--bunpen-run-path" p ]; tryKeepUsers = [ "--bunpen-try-keep-users" ]; whitelistPwd = [ "--bunpen-path" "." ]; }; +in +{ + method, + allowedPaths ? [], + allowedHomePaths ? [], + allowedRunPaths ? [], + autodetectCliPaths ? false, + capabilities ? [], + dns ? null, + keepIpc ? false, + keepPids ? false, + tryKeepUsers ? false, + netDev ? null, + netGateway ? null, + whitelistPwd ? false, + extraConfig ? [], +}: +let gen = if method == "bunpen" then bunpenGenerators else saneboxGenerators ; - allowPaths = flavor: paths: lib.flatten (builtins.map gen."path${flavor}" paths); + allowPaths = flavor: paths: lib.flatten (builtins.map gen.path."${flavor}" paths); capabilityFlags = lib.flatten (builtins.map gen.capability capabilities); netItems = lib.optionals (netDev != null) (gen.netDev netDev) - ++ lib.optionals (netGateway != null) (gen.netGateway netGateway) - ++ lib.optionals (dns != null) (lib.flatten (builtins.map gen.dns dns)) + ++ lib.optionals (netGateway != null) (gen.netGateway netGateway) + ++ lib.optionals (dns != null) (lib.flatten (builtins.map gen.dns dns)) ; in (gen.method method) ++ netItems - ++ allowPaths "" allowedPaths - ++ allowPaths "-home" allowedHomePaths - ++ allowPaths "-run" allowedRunPaths + ++ allowPaths "unqualified" allowedPaths + ++ allowPaths "home" allowedHomePaths + ++ allowPaths "run" allowedRunPaths ++ capabilityFlags ++ lib.optionals (autodetectCliPaths != null) (gen.autodetectCliPaths autodetectCliPaths) ++ lib.optionals keepIpc gen.keepIpc diff --git a/overlays/all.nix b/overlays/all.nix index 4d4e8e2d6..8e9887f96 100644 --- a/overlays/all.nix +++ b/overlays/all.nix @@ -1,14 +1,15 @@ # this overlay exists specifically to control the order in which other overlays are applied. # for example, `pkgs` *must* be added before `cross`, as the latter applies overrides # to the packages defined in the former. - -final: prev: let pkgs = import ./pkgs.nix; preferences = import ./preferences.nix; cross = import ./cross.nix; pkgs-ccache = import ./pkgs-ccache.nix; pkgs-debug = import ./pkgs-debug.nix; +in +final: prev: +let isCross = prev.stdenv.hostPlatform != prev.stdenv.buildPlatform; ifCross = overlay: if isCross then overlay else (_: _: {});