diff options
author | Alex Zero <joseph@marsden.space> | 2021-07-12 02:07:53 +0100 |
---|---|---|
committer | Alex Zero <joseph@marsden.space> | 2021-08-17 15:25:42 +0100 |
commit | b3c424f5a6a4d7c16a42e54de736698d5b21fad5 (patch) | |
tree | d0d92913aab337388147a5317ddae7097e6e0c79 /src/libfetchers/path.cc | |
parent | 2cd1a5b8f31627a09ac34afcbb0f76e90606204f (diff) |
Fix follows paths in subordinate lockfiles
Diffstat (limited to 'src/libfetchers/path.cc')
-rw-r--r-- | src/libfetchers/path.cc | 22 |
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)), |