From 1970d6db12d1b70eda85b92465a6a42a4f1ff54d Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Wed, 18 May 2022 14:20:24 +0200 Subject: [PATCH] Fix showing an appropriate RestrictedPathError --- src/libexpr/eval.cc | 12 ++++++++++-- src/libexpr/nixexpr.hh | 1 - src/libfetchers/input-accessor.cc | 20 +++++++++++++------- src/libfetchers/input-accessor.hh | 7 ++++++- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index eb4455d8f..72e5c98e9 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -461,10 +461,18 @@ EvalState::EvalState( , sPrefix(symbols.create("prefix")) , repair(NoRepair) , emptyBindings(0) - , rootFS(makeFSInputAccessor(CanonPath::root, + , rootFS( + makeFSInputAccessor( + CanonPath::root, evalSettings.restrictEval || evalSettings.pureEval ? std::optional>(std::set()) - : std::nullopt)) + : std::nullopt, + [](const CanonPath & path) -> RestrictedPathError { + auto modeInformation = evalSettings.pureEval + ? "in pure eval mode (use '--impure' to override)" + : "in restricted mode"; + throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation); + })) , corepkgsFS(makeMemoryInputAccessor()) , store(store) , buildStore(buildStore ? buildStore : store) diff --git a/src/libexpr/nixexpr.hh b/src/libexpr/nixexpr.hh index 67e95b2f5..f083d67fd 100644 --- a/src/libexpr/nixexpr.hh +++ b/src/libexpr/nixexpr.hh @@ -20,7 +20,6 @@ MakeError(Abort, EvalError); MakeError(TypeError, EvalError); MakeError(UndefinedVarError, Error); MakeError(MissingArgumentError, EvalError); -MakeError(RestrictedPathError, Error); /* Position objects. */ diff --git a/src/libfetchers/input-accessor.cc b/src/libfetchers/input-accessor.cc index e448b42b5..fb26ced4b 100644 --- a/src/libfetchers/input-accessor.cc +++ b/src/libfetchers/input-accessor.cc @@ -104,10 +104,15 @@ struct FSInputAccessorImpl : FSInputAccessor { CanonPath root; std::optional> allowedPaths; + MakeNotAllowedError makeNotAllowedError; - FSInputAccessorImpl(const CanonPath & root, std::optional> && allowedPaths) + FSInputAccessorImpl( + const CanonPath & root, + std::optional> && allowedPaths, + MakeNotAllowedError && makeNotAllowedError) : root(root) - , allowedPaths(allowedPaths) + , allowedPaths(std::move(allowedPaths)) + , makeNotAllowedError(std::move(makeNotAllowedError)) { } std::string readFile(const CanonPath & path) override @@ -171,9 +176,9 @@ struct FSInputAccessorImpl : FSInputAccessor void checkAllowed(const CanonPath & absPath) override { if (!isAllowed(absPath)) - // FIXME: for Git trees, show a custom error message like - // "file is not under version control or does not exist" - throw Error("access to path '%s' is forbidden", absPath); + throw makeNotAllowedError + ? makeNotAllowedError(absPath) + : RestrictedPathError("access to path '%s' is forbidden", absPath); } bool isAllowed(const CanonPath & absPath) @@ -209,9 +214,10 @@ struct FSInputAccessorImpl : FSInputAccessor ref makeFSInputAccessor( const CanonPath & root, - std::optional> && allowedPaths) + std::optional> && allowedPaths, + MakeNotAllowedError && makeNotAllowedError) { - return make_ref(root, std::move(allowedPaths)); + return make_ref(root, std::move(allowedPaths), std::move(makeNotAllowedError)); } std::ostream & operator << (std::ostream & str, const SourcePath & path) diff --git a/src/libfetchers/input-accessor.hh b/src/libfetchers/input-accessor.hh index df5fd8e7a..d4a3fd40e 100644 --- a/src/libfetchers/input-accessor.hh +++ b/src/libfetchers/input-accessor.hh @@ -7,6 +7,8 @@ namespace nix { +MakeError(RestrictedPathError, Error); + struct InputAccessor { const size_t number; @@ -68,9 +70,12 @@ struct FSInputAccessor : InputAccessor virtual bool hasAccessControl() = 0; }; +typedef std::function MakeNotAllowedError; + ref makeFSInputAccessor( const CanonPath & root, - std::optional> && allowedPaths = {}); + std::optional> && allowedPaths = {}, + MakeNotAllowedError && makeNotAllowedError = {}); struct MemoryInputAccessor : InputAccessor {