modules/programs: handle more symlink forms when calculating a program's sandbox closure
This commit is contained in:
parent
6f59254a22
commit
88a70b41f1
|
@ -10,6 +10,10 @@ in rec {
|
||||||
wantedText = text: wantedSymlink { inherit text; };
|
wantedText = text: wantedSymlink { inherit text; };
|
||||||
|
|
||||||
# Type: derefSymlinkOrNul :: config.sane.fs.type -> str -> (str|null)
|
# Type: derefSymlinkOrNul :: config.sane.fs.type -> str -> (str|null)
|
||||||
|
# N.B.: the returned path, even though absolute, might not be "canonical".
|
||||||
|
# for example, if the symlink is relative, to "../Pictures", this function
|
||||||
|
# could return "/home/colin/Music/../Pictures".
|
||||||
|
# consider feeding the output into `sane-lib.path.realpath` to correct this.
|
||||||
derefSymlinkOrNull = fs: logical: let
|
derefSymlinkOrNull = fs: logical: let
|
||||||
symlinkedPrefixes = lib.filter
|
symlinkedPrefixes = lib.filter
|
||||||
(p: ((fs."${p}" or {}).symlink or null) != null)
|
(p: ((fs."${p}" or {}).symlink or null) != null)
|
||||||
|
@ -20,7 +24,6 @@ in rec {
|
||||||
firstSymlinkDestAbs = if lib.hasPrefix "/" firstSymlinkDest then
|
firstSymlinkDestAbs = if lib.hasPrefix "/" firstSymlinkDest then
|
||||||
firstSymlinkDest
|
firstSymlinkDest
|
||||||
else
|
else
|
||||||
# TODO: path canonicalization (for i.e. relative symlinks)
|
|
||||||
sane-path.join [ firstSymlinkParent firstSymlinkDest ];
|
sane-path.join [ firstSymlinkParent firstSymlinkDest ];
|
||||||
in
|
in
|
||||||
if symlinkedPrefixes != [] then
|
if symlinkedPrefixes != [] then
|
||||||
|
|
|
@ -20,6 +20,22 @@ let path = rec {
|
||||||
# always starting with '/', never trailing with '/' unless it's the empty (root) path
|
# always starting with '/', never trailing with '/' unless it's the empty (root) path
|
||||||
norm = str: path.join (path.split str);
|
norm = str: path.join (path.split str);
|
||||||
|
|
||||||
|
# removes ".." and "." components from a path component list, by evaluating them logically.
|
||||||
|
# Type realpathArray: [ str ] -> [ str ]
|
||||||
|
realpathArray = arr: lib.foldl'
|
||||||
|
(acc: next:
|
||||||
|
if next == ".." then lib.init acc
|
||||||
|
else if next == "." then acc
|
||||||
|
else acc ++ [ next ]
|
||||||
|
)
|
||||||
|
[]
|
||||||
|
arr
|
||||||
|
;
|
||||||
|
# removes ".." and "." from a path, by evaluating them logically.
|
||||||
|
# has the effect of also normalizing the path, in the process.
|
||||||
|
# Type realpath: str -> str
|
||||||
|
realpath = str: path.join (path.realpathArray (path.split str));
|
||||||
|
|
||||||
# return the parent directory. doesn't care about leading/trailing slashes.
|
# return the parent directory. doesn't care about leading/trailing slashes.
|
||||||
# the parent of "/" is "/".
|
# the parent of "/" is "/".
|
||||||
parent = str: path.norm (builtins.dirOf (path.norm str));
|
parent = str: path.norm (builtins.dirOf (path.norm str));
|
||||||
|
|
|
@ -46,11 +46,12 @@ let
|
||||||
# removeStorePaths: [ str ] -> [ str ], but remove store paths, because nix evals aren't allowed to contain any (for purity reasons?)
|
# removeStorePaths: [ str ] -> [ str ], but remove store paths, because nix evals aren't allowed to contain any (for purity reasons?)
|
||||||
removeStorePaths = paths: lib.filter (p: !(lib.hasPrefix "/nix/store" p)) paths;
|
removeStorePaths = paths: lib.filter (p: !(lib.hasPrefix "/nix/store" p)) paths;
|
||||||
|
|
||||||
|
makeCanonical = paths: builtins.map path-lib.realpath paths;
|
||||||
# derefSymlinks: [ str ] -> [ str ]: for each path which is a symlink (or a child of a symlink'd dir), dereference one layer of symlink. else, drop it from the list.
|
# derefSymlinks: [ str ] -> [ str ]: for each path which is a symlink (or a child of a symlink'd dir), dereference one layer of symlink. else, drop it from the list.
|
||||||
derefSymlinks' = paths: builtins.map (fs-lib.derefSymlinkOrNull config.sane.fs) paths;
|
derefSymlinks' = paths: builtins.map (fs-lib.derefSymlinkOrNull config.sane.fs) paths;
|
||||||
derefSymlinks = paths: lib.filter (p: p != null) (derefSymlinks' paths);
|
derefSymlinks = paths: lib.filter (p: p != null) (derefSymlinks' paths);
|
||||||
# expandSymlinksOnce: [ str ] -> [ str ], returning all the original paths plus dereferencing any symlinks and adding their targets to this list.
|
# expandSymlinksOnce: [ str ] -> [ str ], returning all the original paths plus dereferencing any symlinks and adding their targets to this list.
|
||||||
expandSymlinksOnce = paths: lib.unique (paths ++ removeStorePaths (derefSymlinks paths));
|
expandSymlinksOnce = paths: lib.unique (paths ++ removeStorePaths (makeCanonical (derefSymlinks paths)));
|
||||||
expandSymlinks = paths: lib.converge expandSymlinksOnce paths;
|
expandSymlinks = paths: lib.converge expandSymlinksOnce paths;
|
||||||
|
|
||||||
vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn);
|
vpn = lib.findSingle (v: v.default) null null (builtins.attrValues config.sane.vpn);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user