diff options
author | regnat <rg@regnat.ovh> | 2021-12-23 10:35:09 +0100 |
---|---|---|
committer | regnat <rg@regnat.ovh> | 2021-12-23 10:49:33 +0100 |
commit | dc89dfa7b3f8fa7368cd4c5e20891e60e418722b (patch) | |
tree | adfec92a6cc1208a01a2a5f66709c9ec93b7b18b /src | |
parent | 7feb741e002a7ae108858fcafe67e1f429862775 (diff) |
Properly return false on `builtins.pathExists /someNonAllowedPath`
Follow-up from https://github.com/NixOS/nix/pull/5807 to fix https://github.com/NixOS/nix/pull/5807#issuecomment-1000135394
Diffstat (limited to 'src')
-rw-r--r-- | src/libexpr/primops.cc | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index aff8f951e..62c21c7c5 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -89,18 +89,28 @@ StringMap EvalState::realiseContext(const PathSet & context) return res; } -static Path realisePath(EvalState & state, const Pos & pos, Value & v, bool requireAbsolutePath = true) +struct RealisePathFlags { + // Whether to check whether the path is a valid absolute path + bool requireAbsolutePath = true; + // Whether to check that the path is allowed in pure eval mode + bool checkForPureEval = true; +}; + +static Path realisePath(EvalState & state, const Pos & pos, Value & v, const RealisePathFlags flags = {}) { PathSet context; - Path path = requireAbsolutePath + Path path = flags.requireAbsolutePath ? state.coerceToPath(pos, v, context) : state.coerceToString(pos, v, context, false, false); StringMap rewrites = state.realiseContext(context); - return state.checkSourcePath( - state.toRealPath(rewriteStrings(path, rewrites), context)); + auto realPath = state.toRealPath(rewriteStrings(path, rewrites), context); + + return flags.checkForPureEval + ? state.checkSourcePath(realPath) + : realPath; } /* Add and attribute to the given attribute map from the output name to @@ -1371,7 +1381,12 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, { Path path; try { - path = realisePath(state, pos, *args[0]); + // We don’t check the path right now, because we don’t want to throw if + // the path isn’t allowed, but just return false + // (and we can’t just catch the exception here because we still want to + // throw if something in the evaluation of `*args[0]` tries to access an + // unauthorized path) + path = realisePath(state, pos, *args[0], { .checkForPureEval = false }); } catch (InvalidPathError & e) { throw EvalError({ .msg = hintfmt( @@ -1382,7 +1397,7 @@ static void prim_pathExists(EvalState & state, const Pos & pos, Value * * args, } try { - mkBool(v, pathExists(path)); + mkBool(v, pathExists(state.checkSourcePath(path))); } catch (SysError & e) { /* Don't give away info from errors while canonicalising ‘path’ in restricted mode. */ @@ -1496,7 +1511,7 @@ static void prim_findFile(EvalState & state, const Pos & pos, Value * * args, Va Path path; try { - path = realisePath(state, pos, *i->value, false); + path = realisePath(state, pos, *i->value, { .requireAbsolutePath = false }); } catch (InvalidPathError & e) { throw EvalError({ .msg = hintfmt("cannot find '%1%', since path '%2%' is not valid", path, e.path), |