aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEelco Dolstra <edolstra@gmail.com>2021-10-07 14:07:51 +0200
committerEelco Dolstra <edolstra@gmail.com>2021-10-07 14:22:39 +0200
commitd39692e6b3275c6f54c066554d2915e4b857bc3e (patch)
tree2b30790e1532e330ca5037b621fe30df8fe0de90
parent7b5fc4a984a2db7c90e7fc884e2e0c076ad07df7 (diff)
Make builtins.{path,filterSource} work with chroot stores
-rw-r--r--src/libexpr/eval.cc10
-rw-r--r--src/libexpr/eval.hh4
-rw-r--r--src/libexpr/flake/flake.cc2
-rw-r--r--src/libexpr/primops.cc13
-rw-r--r--src/libexpr/primops/fetchMercurial.cc2
-rw-r--r--src/libexpr/primops/fetchTree.cc8
6 files changed, 24 insertions, 15 deletions
diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc
index 2483132f6..3ae05a8d8 100644
--- a/src/libexpr/eval.cc
+++ b/src/libexpr/eval.cc
@@ -445,7 +445,7 @@ EvalState::EvalState(
StorePathSet closure;
store->computeFSClosure(store->toStorePath(r.second).first, closure);
for (auto & path : closure)
- allowPath(store->printStorePath(path));
+ allowPath(path);
} catch (InvalidPath &) {
allowPath(r.second);
}
@@ -488,6 +488,12 @@ void EvalState::allowPath(const Path & path)
allowedPaths->insert(path);
}
+void EvalState::allowPath(const StorePath & storePath)
+{
+ if (allowedPaths)
+ allowedPaths->insert(store->toRealPath(storePath));
+}
+
Path EvalState::checkSourcePath(const Path & path_)
{
if (!allowedPaths) return path_;
@@ -1895,9 +1901,9 @@ string EvalState::copyPathToStore(PathSet & context, const Path & path)
? store->computeStorePathForPath(std::string(baseNameOf(path)), checkSourcePath(path)).first
: store->addToStore(std::string(baseNameOf(path)), checkSourcePath(path), FileIngestionMethod::Recursive, htSHA256, defaultPathFilter, repair);
dstPath = store->printStorePath(p);
+ allowPath(p);
srcToStore.insert_or_assign(path, std::move(p));
printMsg(lvlChatty, "copied source '%1%' -> '%2%'", path, dstPath);
- allowPath(dstPath);
}
context.insert(dstPath);
diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh
index f8c9cf5a7..7cc16ef0a 100644
--- a/src/libexpr/eval.hh
+++ b/src/libexpr/eval.hh
@@ -153,6 +153,10 @@ public:
/* Allow access to a path. */
void allowPath(const Path & path);
+ /* Allow access to a store path. Note that this gets remapped to
+ the real store path if `store` is a chroot store. */
+ void allowPath(const StorePath & storePath);
+
/* Check whether access to a path is allowed and throw an error if
not. Otherwise return the canonicalised path. */
Path checkSourcePath(const Path & path);
diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc
index abb0fb0be..43bfc3644 100644
--- a/src/libexpr/flake/flake.cc
+++ b/src/libexpr/flake/flake.cc
@@ -64,7 +64,7 @@ static std::tuple<fetchers::Tree, FlakeRef, FlakeRef> fetchOrSubstituteTree(
debug("got tree '%s' from '%s'",
state.store->printStorePath(tree.storePath), lockedRef);
- state.allowPath(tree.actualPath);
+ state.allowPath(tree.storePath);
assert(!originalRef.input.getNarHash() || tree.storePath == originalRef.input.computeStorePath(*state.store));
diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc
index 94e196d62..f27331534 100644
--- a/src/libexpr/primops.cc
+++ b/src/libexpr/primops.cc
@@ -1859,18 +1859,19 @@ static void addPath(
// be rewritten to the actual output).
state.realiseContext(context);
- path = evalSettings.pureEval && expectedHash
- ? path
- : state.checkSourcePath(path);
-
if (state.store->isInStore(path)) {
- auto storePath = state.store->toStorePath(path).first;
+ auto [storePath, subPath] = state.store->toStorePath(path);
auto info = state.store->queryPathInfo(storePath);
if (!info->references.empty())
throw EvalError("store path '%s' is not allowed to have references",
state.store->printStorePath(storePath));
+ path = state.store->toRealPath(storePath) + subPath;
}
+ path = evalSettings.pureEval && expectedHash
+ ? path
+ : state.checkSourcePath(path);
+
PathFilter filter = filterFun ? ([&](const Path & path) {
auto st = lstat(path);
@@ -1911,7 +1912,7 @@ static void addPath(
mkString(v, dstPath, {dstPath});
- state.allowPath(v.string.s);
+ state.allowPath(dstPath);
} catch (Error & e) {
e.addTrace(pos, "while adding path '%s'", path);
diff --git a/src/libexpr/primops/fetchMercurial.cc b/src/libexpr/primops/fetchMercurial.cc
index b51b155f7..1cd481243 100644
--- a/src/libexpr/primops/fetchMercurial.cc
+++ b/src/libexpr/primops/fetchMercurial.cc
@@ -84,7 +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();
- state.allowPath(tree.actualPath);
+ state.allowPath(tree.storePath);
}
static RegisterPrimOp r_fetchMercurial("fetchMercurial", 1, prim_fetchMercurial);
diff --git a/src/libexpr/primops/fetchTree.cc b/src/libexpr/primops/fetchTree.cc
index 44f726f9b..f570f19ae 100644
--- a/src/libexpr/primops/fetchTree.cc
+++ b/src/libexpr/primops/fetchTree.cc
@@ -169,7 +169,7 @@ static void fetchTree(
auto [tree, input2] = input.fetch(state.store);
- state.allowPath(tree.actualPath);
+ state.allowPath(tree.storePath);
emitTreeAttrs(state, tree, input2, v, params.emptyRevFallback, false);
}
@@ -233,18 +233,16 @@ static void fetch(EvalState & state, const Pos & pos, Value * * args, Value & v,
? fetchers::downloadTarball(state.store, *url, name, (bool) expectedHash).first.storePath
: fetchers::downloadFile(state.store, *url, name, (bool) expectedHash).storePath;
- auto realPath = state.store->toRealPath(storePath);
-
if (expectedHash) {
auto hash = unpack
? state.store->queryPathInfo(storePath)->narHash
- : hashFile(htSHA256, realPath);
+ : hashFile(htSHA256, state.store->toRealPath(storePath));
if (hash != *expectedHash)
throw Error((unsigned int) 102, "hash mismatch in file downloaded from '%s':\n specified: %s\n got: %s",
*url, expectedHash->to_string(Base32, true), hash.to_string(Base32, true));
}
- state.allowPath(realPath);
+ state.allowPath(storePath);
auto path = state.store->printStorePath(storePath);
mkString(v, path, PathSet({path}));