aboutsummaryrefslogtreecommitdiff
path: root/src/libfetchers/path.cc
diff options
context:
space:
mode:
authorAlex Zero <joseph@marsden.space>2021-07-12 02:07:53 +0100
committerAlex Zero <joseph@marsden.space>2021-08-17 15:25:42 +0100
commitb3c424f5a6a4d7c16a42e54de736698d5b21fad5 (patch)
treed0d92913aab337388147a5317ddae7097e6e0c79 /src/libfetchers/path.cc
parent2cd1a5b8f31627a09ac34afcbb0f76e90606204f (diff)
Fix follows paths in subordinate lockfiles
Diffstat (limited to 'src/libfetchers/path.cc')
-rw-r--r--src/libfetchers/path.cc22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/libfetchers/path.cc b/src/libfetchers/path.cc
index d1003de57..c4977834d 100644
--- a/src/libfetchers/path.cc
+++ b/src/libfetchers/path.cc
@@ -82,18 +82,34 @@ struct PathInputScheme : InputScheme
std::pair<Tree, Input> fetch(ref<Store> store, const Input & input) override
{
+ std::string absPath;
auto path = getStrAttr(input.attrs, "path");
- // FIXME: check whether access to 'path' is allowed.
+ if (path[0] != '/' && input.parent)
+ {
+ auto parent = canonPath(*input.parent);
+
+ // the path isn't relative, prefix it
+ absPath = canonPath(parent + "/" + path);
- auto storePath = store->maybeParseStorePath(path);
+ // 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);
+ }
+ else
+ {
+ absPath = path;
+ }
+
+ // FIXME: check whether access to 'path' is allowed.
+ auto storePath = store->maybeParseStorePath(absPath);
if (storePath)
store->addTempRoot(*storePath);
if (!storePath || storePath->name() != "source" || !store->isValidPath(*storePath))
// FIXME: try to substitute storePath.
- storePath = store->addToStore("source", path);
+ storePath = store->addToStore("source", absPath);
return {
Tree(store->toRealPath(*storePath), std::move(*storePath)),