diff options
Diffstat (limited to 'src/libexpr/eval.cc')
-rw-r--r-- | src/libexpr/eval.cc | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 95b56e84d89a..d82d1d6aafa2 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -195,6 +195,8 @@ EvalState::EvalState(const Strings & _searchPath) nrListConcats = nrPrimOpCalls = nrFunctionCalls = 0; countCalls = getEnv("NIX_COUNT_CALLS", "0") != "0"; + restricted = settings.get("restrict-eval", false); + #if HAVE_BOEHMGC static bool gcInitialised = false; if (!gcInitialised) { @@ -250,6 +252,21 @@ EvalState::~EvalState() } +Path EvalState::checkSourcePath(const Path & path_) +{ + if (!restricted) return path_; + + /* Resolve symlinks. */ + Path path = canonPath(path_, true); + + for (auto & i : searchPath) + if (path == i.second || isInDir(path, i.second)) + return path; + + throw RestrictedPathError(format("access to path ‘%1%’ is forbidden in restricted mode") % path_); +} + + void EvalState::addConstant(const string & name, Value & v) { Value * v2 = allocValue(); @@ -555,7 +572,7 @@ void EvalState::evalFile(const Path & path, Value & v) } startNest(nest, lvlTalkative, format("evaluating file ‘%1%’") % path2); - Expr * e = parseExprFromFile(path2); + Expr * e = parseExprFromFile(checkSourcePath(path2)); try { eval(e, v); } catch (Error & e) { @@ -1358,8 +1375,8 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) dstPath = srcToStore[path]; else { dstPath = settings.readOnlyMode - ? computeStorePathForPath(path).first - : store->addToStore(path, true, htSHA256, defaultPathFilter, repair); + ? computeStorePathForPath(checkSourcePath(path)).first + : store->addToStore(checkSourcePath(path), true, htSHA256, defaultPathFilter, repair); srcToStore[path] = dstPath; printMsg(lvlChatty, format("copied source ‘%1%’ -> ‘%2%’") % path % dstPath); |