diff options
| author | Reepca Russelstein <reepca@russelstein.xyz> | 2026-06-21 07:28:58 -0500 |
|---|---|---|
| committer | Ludovic Courtès <ludo@gnu.org> | 2026-06-24 15:20:16 +0200 |
| commit | 247245fbef1923a3bc17a23627e9c016900b4edc (patch) | |
| tree | ac70e5c649e39ce49b6271e7f30432c1fa50bff4 /nix/libstore/local-store.cc | |
| parent | 69b37a8e5d166328fa3d9a7c61b7ca1dfa772552 (diff) | |
daemon: libstore: reject invalid store paths in importPath.
Previously an authorized substitute server could produce invalid store paths -
that is, paths that do denote a top-level file in the store, but that do not
obey the syntax restrictions beyond what that implies. Given that an
authorized substitute server can already potentially do a lot of damage if it
really wanted to, this isn't a major issue, but closing off this opportunity
does simplify the analysis somewhat.
* nix/libstore/local-store.cc (LocalStore::importPath): use
strict readStorePath(s) variants.
* tests/store.scm ("import path not in store, unsigned", "import path not in
store, signed", "import invalid path, unsigned", "import invalid path,
signed" test cases): new test cases. The "not in store" cases succeeded
previously, while the "invalid path" cases did not succeed prior to this
commit.
Fixes: guix/guix#9078
Change-Id: Ib81c19ec1ae0fff5b7c7268f4f7429b16a870996
Signed-off-by: Ludovic Courtès <ludo@gnu.org>
Merges: #9434
Diffstat (limited to 'nix/libstore/local-store.cc')
| -rw-r--r-- | nix/libstore/local-store.cc | 10 |
1 files changed, 7 insertions, 3 deletions
diff --git a/nix/libstore/local-store.cc b/nix/libstore/local-store.cc index b8308b1aae5..478f2ccc44f 100644 --- a/nix/libstore/local-store.cc +++ b/nix/libstore/local-store.cc | |||
| @@ -1340,12 +1340,16 @@ Path LocalStore::importPath(bool requireSignature, Source & source) | |||
| 1340 | if (magic != EXPORT_MAGIC) | 1340 | if (magic != EXPORT_MAGIC) |
| 1341 | throw Error("normalized archive cannot be imported; wrong format"); | 1341 | throw Error("normalized archive cannot be imported; wrong format"); |
| 1342 | 1342 | ||
| 1343 | Path dstPath = readStorePath(hashAndReadSource); | 1343 | /* The path being imported must at least be syntactically valid. This |
| 1344 | * doesn't guarantee that it can be constructed by some existing method, | ||
| 1345 | * but it at least rules out paths like "/gnu/store/nix-12982-1" or | ||
| 1346 | * "/gnu/store/." or "/gnu/store/..". */ | ||
| 1347 | Path dstPath = readStorePathStrict(hashAndReadSource); | ||
| 1344 | 1348 | ||
| 1345 | PathSet references = readStorePaths<PathSet>(hashAndReadSource); | 1349 | PathSet references = readStorePathsStrict<PathSet>(hashAndReadSource); |
| 1346 | 1350 | ||
| 1347 | Path deriver = readString(hashAndReadSource); | 1351 | Path deriver = readString(hashAndReadSource); |
| 1348 | if (deriver != "") assertStorePath(deriver); | 1352 | if (deriver != "") assertStorePathStrict(deriver); |
| 1349 | 1353 | ||
| 1350 | Hash hash = hashAndReadSource.hashSink.finish().first; | 1354 | Hash hash = hashAndReadSource.hashSink.finish().first; |
| 1351 | hashAndReadSource.hashing = false; | 1355 | hashAndReadSource.hashing = false; |
