From cad16830484e4b47007f10c3c06cef153b78c992 Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Mon, 4 Mar 2024 06:03:33 +0100 Subject: [PATCH] Merge pull request #9398 from Qyriad/fixes/flake-not-found flakes: bare minimum fix the error message for untracked flake.nix (cherry picked from commit 7f626dba332f320fafb9f9c749986ea523d20f42) Change-Id: I470ac56a670a8c11e4164c6b059184a02344d491 --- src/libexpr/flake/flake.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 90427e064..e1f41a8a2 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -205,8 +205,16 @@ static Flake getFlake( auto [sourceInfo, resolvedRef, lockedRef] = fetchOrSubstituteTree( state, originalRef, allowLookup, flakeCache); + // We need to guard against symlink attacks, but before we start doing + // filesystem operations we should make sure there's a flake.nix in the + // first place. + auto unsafeFlakeDir = sourceInfo.actualPath + "/" + lockedRef.subdir; + auto unsafeFlakeFile = unsafeFlakeDir + "/flake.nix"; + if (!pathExists(unsafeFlakeFile)) + throw Error("source tree referenced by '%s' does not contain a '%s/flake.nix' file", lockedRef, lockedRef.subdir); + // Guard against symlink attacks. - auto flakeDir = canonPath(sourceInfo.actualPath + "/" + lockedRef.subdir, true); + auto flakeDir = canonPath(unsafeFlakeDir, true); auto flakeFile = canonPath(flakeDir + "/flake.nix", true); if (!isInDir(flakeFile, sourceInfo.actualPath)) throw Error("'flake.nix' file of flake '%s' escapes from '%s'", @@ -219,9 +227,6 @@ static Flake getFlake( .sourceInfo = std::make_shared(std::move(sourceInfo)) }; - if (!pathExists(flakeFile)) - throw Error("source tree referenced by '%s' does not contain a '%s/flake.nix' file", lockedRef, lockedRef.subdir); - Value vInfo; state.evalFile(CanonPath(flakeFile), vInfo, true); // FIXME: symlink attack