aboutsummaryrefslogtreecommitdiff
path: root/src/libexpr/flake/flake.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libexpr/flake/flake.cc')
-rw-r--r--src/libexpr/flake/flake.cc13
1 files 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<fetchers::Tree>(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