From cfaad7168e7ac72d4b2024df2e093b86b45b70fc Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 7 Oct 2021 12:11:00 +0200 Subject: [PATCH 1/2] Refactoring: Add allowPath() method --- src/libexpr/eval.cc | 12 +++++++++--- src/libexpr/eval.hh | 5 +++++ src/libexpr/flake/flake.cc | 3 +-- src/libexpr/primops.cc | 3 +-- src/libexpr/primops/fetchMercurial.cc | 3 +-- src/libexpr/primops/fetchTree.cc | 6 ++---- src/nix/profile.cc | 6 ++---- 7 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 2a79090cd..ce266f522 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -445,12 +445,12 @@ EvalState::EvalState( StorePathSet closure; store->computeFSClosure(store->toStorePath(r.second).first, closure); for (auto & path : closure) - allowedPaths->insert(store->printStorePath(path)); + allowPath(store->printStorePath(path)); } catch (InvalidPath &) { - allowedPaths->insert(r.second); + allowPath(r.second); } } else - allowedPaths->insert(r.second); + allowPath(r.second); } } @@ -482,6 +482,12 @@ void EvalState::requireExperimentalFeatureOnEvaluation( } } +void EvalState::allowPath(const Path & path) +{ + if (allowedPaths) + allowedPaths->insert(path); +} + Path EvalState::checkSourcePath(const Path & path_) { if (!allowedPaths) return path_; diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 9df6150c6..f8c9cf5a7 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -150,6 +150,11 @@ public: SearchPath getSearchPath() { return searchPath; } + /* Allow access to a path. */ + void allowPath(const Path & path); + + /* Check whether access to a path is allowed and throw an error if + not. Otherwise return the canonicalised path. */ Path checkSourcePath(const Path & path); void checkURI(const std::string & uri); diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 6a2902dff..abb0fb0be 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -64,8 +64,7 @@ static std::tuple fetchOrSubstituteTree( debug("got tree '%s' from '%s'", state.store->printStorePath(tree.storePath), lockedRef); - if (state.allowedPaths) - state.allowedPaths->insert(tree.actualPath); + state.allowPath(tree.actualPath); assert(!originalRef.input.getNarHash() || tree.storePath == originalRef.input.computeStorePath(*state.store)); diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 749afadd0..1b79785ff 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -1892,8 +1892,7 @@ static void addPath(EvalState & state, const Pos & pos, const string & name, con mkString(v, dstPath, {dstPath}); - if (state.allowedPaths) - state.allowedPaths->insert(v.string.s); + state.allowPath(v.string.s); } diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc index 3f88ccb91..b51b155f7 100644 --- a/src/libexpr/primops/fetchMercurial.cc +++ b/src/libexpr/primops/fetchMercurial.cc @@ -84,8 +84,7 @@ static void prim_fetchMercurial(EvalState & state, const Pos & pos, Value * * ar mkInt(*state.allocAttr(v, state.symbols.create("revCount")), *revCount); v.attrs->sort(); - if (state.allowedPaths) - state.allowedPaths->insert(tree.actualPath); + state.allowPath(tree.actualPath); } static RegisterPrimOp r_fetchMercurial("fetchMercurial", 1, prim_fetchMercurial); diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc index 1a69fe4e4..44f726f9b 100644 --- a/src/libexpr/primops/fetchTree.cc +++ b/src/libexpr/primops/fetchTree.cc @@ -169,8 +169,7 @@ static void fetchTree( auto [tree, input2] = input.fetch(state.store); - if (state.allowedPaths) - state.allowedPaths->insert(tree.actualPath); + state.allowPath(tree.actualPath); emitTreeAttrs(state, tree, input2, v, params.emptyRevFallback, false); } @@ -245,8 +244,7 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v, *url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true)); } - if (state.allowedPaths) - state.allowedPaths->insert(realPath); + state.allowPath(realPath); auto path = state.store->printStorePath(storePath); mkString(v, path, PathSet({path})); diff --git a/src/nix/profile.cc b/src/nix/profile.cc index c63ed9c88..96a20f673 100644 --- a/src/nix/profile.cc +++ b/src/nix/profile.cc @@ -98,10 +98,8 @@ struct ProfileManifest else if (pathExists(profile + "/manifest.nix")) { // FIXME: needed because of pure mode; ugly. - if (state.allowedPaths) { - state.allowedPaths->insert(state.store->followLinksToStore(profile)); - state.allowedPaths->insert(state.store->followLinksToStore(profile + "/manifest.nix")); - } + state.allowPath(state.store->followLinksToStore(profile)); + state.allowPath(state.store->followLinksToStore(profile + "/manifest.nix")); auto drvInfos = queryInstalled(state, state.store->followLinksToStore(profile)); From 972405edf5ff0d90185fb4021993c4a942787578 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 7 Oct 2021 12:15:22 +0200 Subject: [PATCH 2/2] Allow access to path copied to the store Fixes https://github.com/NixOS/nix/pull/5163#issuecomment-931733912. --- src/libexpr/eval.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index ce266f522..2483132f6 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1897,6 +1897,7 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path) dstPath = store->printStorePath(p); srcToStore.insert_or_assign(path, std::move(p)); printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, dstPath); + allowPath(dstPath); } context.insert(dstPath);