From 2bf25214f9b23a1aa9510dc967f816e09169b10b Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Fri, 13 Dec 2024 16:49:48 +0100 Subject: [PATCH 1/3] EvalState::realiseContext(): Allow access to the entire closure Fixes #11030. (cherry picked from commit 08361f031d65703aa35cb3b7e7715ff63256e311) # Conflicts: # src/libexpr/eval.cc # tests/functional/import-from-derivation.nix --- src/libexpr/eval.cc | 14 +++++++++++++ src/libexpr/eval.hh | 5 +++++ src/libexpr/primops.cc | 8 +++---- tests/functional/import-from-derivation.nix | 23 +++++++++++++++++++++ tests/functional/import-from-derivation.sh | 5 +++++ 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index e21f70553a7..0e1bc896b11 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -347,6 +347,16 @@ void EvalState::allowPath(const StorePath & storePath) rootFS2->allowPrefix(CanonPath(store->toRealPath(storePath))); } +void EvalState::allowClosure(const StorePath & storePath) +{ + if (!rootFS.dynamic_pointer_cast()) return; + + StorePathSet closure; + store->computeFSClosure(storePath, closure); + for (auto & p : closure) + allowPath(p); +} + void EvalState::allowAndSetStorePathString(const StorePath & storePath, Value & v) { allowPath(storePath); @@ -3090,10 +3100,14 @@ std::optional EvalState::resolveLookupPathPath(const LookupPath::Pa allowPath(path); if (store->isInStore(path)) { try { +<<<<<<< HEAD StorePathSet closure; store->computeFSClosure(store->toStorePath(path).first, closure); for (auto & p : closure) allowPath(p); +======= + allowClosure(store->toStorePath(path.path.abs()).first); +>>>>>>> 08361f031 (EvalState::realiseContext(): Allow access to the entire closure) } catch (InvalidPath &) { } } } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 7fe70af31b6..0e3ce416451 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -400,6 +400,11 @@ public: */ void allowPath(const StorePath & storePath); + /** + * Allow access to the closure of a store path. + */ + void allowClosure(const StorePath & storePath); + /** * Allow access to a store path and return it as a string. */ diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 45d9f86ac05..5dc87cdac1b 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -121,11 +121,9 @@ StringMap EvalState::realiseContext(const NixStringContext & context, StorePathS if (store != buildStore) copyClosure(*buildStore, *store, outputsToCopyAndAllow); if (isIFD) { - for (auto & outputPath : outputsToCopyAndAllow) { - /* Add the output of this derivations to the allowed - paths. */ - allowPath(outputPath); - } + /* Allow access to the output closures of this derivation. */ + for (auto & outputPath : outputsToCopyAndAllow) + allowClosure(outputPath); } return res; diff --git a/tests/functional/import-from-derivation.nix b/tests/functional/import-from-derivation.nix index 8864fb30af5..c8186a81548 100644 --- a/tests/functional/import-from-derivation.nix +++ b/tests/functional/import-from-derivation.nix @@ -1,4 +1,8 @@ +<<<<<<< HEAD with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix"; +======= +with import ; +>>>>>>> 08361f031 (EvalState::realiseContext(): Allow access to the entire closure) rec { bar = mkDerivation { @@ -30,4 +34,23 @@ rec { echo -n BLA$(cat $src) > $out ''; }; + + step1 = mkDerivation { + name = "step1"; + buildCommand = '' + mkdir -p $out + echo 'foo' > $out/bla + ''; + }; + + addPathExpr = mkDerivation { + name = "add-path"; + inherit step1; + buildCommand = '' + mkdir -p $out + echo "builtins.path { path = \"$step1\"; sha256 = \"7ptL+pnrZXnSa5hwwB+2SXTLkcSb5264WGGokN8OXto=\"; }" > $out/default.nix + ''; + }; + + importAddPathExpr = import addPathExpr; } diff --git a/tests/functional/import-from-derivation.sh b/tests/functional/import-from-derivation.sh index 83ef92a6f58..a007612350c 100755 --- a/tests/functional/import-from-derivation.sh +++ b/tests/functional/import-from-derivation.sh @@ -6,6 +6,8 @@ TODO_NixOS clearStoreIfPossible +export NIX_PATH=config="${config_nix}" + if nix-instantiate --readonly-mode ./import-from-derivation.nix -A result; then echo "read-only evaluation of an imported derivation unexpectedly failed" exit 1 @@ -15,6 +17,9 @@ outPath=$(nix-build ./import-from-derivation.nix -A result --no-out-link) [ "$(cat "$outPath")" = FOO579 ] +# Check that we can have access to the entire closure of a derivation output. +nix build --no-link --restrict-eval -I src=. -f ./import-from-derivation.nix importAddPathExpr -v + # FIXME: the next tests are broken on CA. if [[ -n "${NIX_TESTS_CA_BY_DEFAULT:-}" ]]; then exit 0 From 63749b33fe99182e4e6d66f2464ef848fe9bb63e Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Mon, 16 Dec 2024 18:01:52 +0100 Subject: [PATCH 2/3] Resolve merge conflict (cherry picked from commit a924db7d0b0e23ea39c59c76933111c44703dbfc) --- src/libexpr/eval.cc | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 0e1bc896b11..1edff2b6323 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -3100,14 +3100,7 @@ std::optional EvalState::resolveLookupPathPath(const LookupPath::Pa allowPath(path); if (store->isInStore(path)) { try { -<<<<<<< HEAD - StorePathSet closure; - store->computeFSClosure(store->toStorePath(path).first, closure); - for (auto & p : closure) - allowPath(p); -======= - allowClosure(store->toStorePath(path.path.abs()).first); ->>>>>>> 08361f031 (EvalState::realiseContext(): Allow access to the entire closure) + allowClosure(store->toStorePath(path).first); } catch (InvalidPath &) { } } } From de4c78459b1a1a5aa358d4bb6ce6c744ebfc9c12 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Wed, 1 Jan 2025 03:12:10 +0100 Subject: [PATCH 3/3] Resolve conflict --- tests/functional/import-from-derivation.nix | 4 ---- 1 file changed, 4 deletions(-) diff --git a/tests/functional/import-from-derivation.nix b/tests/functional/import-from-derivation.nix index c8186a81548..7b0031eba9d 100644 --- a/tests/functional/import-from-derivation.nix +++ b/tests/functional/import-from-derivation.nix @@ -1,8 +1,4 @@ -<<<<<<< HEAD with import "${builtins.getEnv "_NIX_TEST_BUILD_DIR"}/config.nix"; -======= -with import ; ->>>>>>> 08361f031 (EvalState::realiseContext(): Allow access to the entire closure) rec { bar = mkDerivation {