From 5cbb9c5406f3058fcc9f99692490fbc5a4f57876 Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Tue, 21 Sep 2021 13:19:26 +0200 Subject: [PATCH] path fetcher: Fix relative path check --- src/libfetchers/path.cc | 13 +++++++++---- tests/flakes.sh | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc index b6fcdac9e..b35c04cfc 100644 --- a/src/libfetchers/path.cc +++ b/src/libfetchers/path.cc @@ -85,18 +85,23 @@ struct PathInputScheme : InputScheme std::string absPath; auto path = getStrAttr(input.attrs, "path"); - if (path[0] != '/' && input.parent) { + if (path[0] != '/') { + if (!input.parent) + throw Error("cannot fetch input '%s' because it uses a relative path", input.to_string()); + auto parent = canonPath(*input.parent); // the path isn't relative, prefix it - absPath = canonPath(parent + "/" + path); + absPath = nix::absPath(path, parent); // for security, ensure that if the parent is a store path, it's inside it - if (!parent.rfind(store->storeDir, 0) && absPath.rfind(store->storeDir, 0)) - throw BadStorePath("relative path '%s' points outside of its parent's store path %s, this is a security violation", path, parent); + if (store->isInStore(parent) && !isInDir(absPath, parent)) + throw BadStorePath("relative path '%s' [%s] points outside of its parent's store path '%s'", path, absPath, parent); } else absPath = path; + Activity act(*logger, lvlTalkative, actUnknown, fmt("copying '%s'", absPath)); + // FIXME: check whether access to 'path' is allowed. auto storePath = store->maybeParseStorePath(absPath); diff --git a/tests/flakes.sh b/tests/flakes.sh index 2ede7f72c..26cdf27b7 100644 --- a/tests/flakes.sh +++ b/tests/flakes.sh @@ -766,7 +766,7 @@ cat > $flakeFollowsA/flake.nix <&1 | grep 'this is a security violation' +nix flake lock $flakeFollowsA 2>&1 | grep 'points outside' # Test flake in store does not evaluate rm -rf $badFlakeDir