diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2010-03-09T14·32+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2010-03-09T14·32+0000 |
commit | 4c356acd044dffbf459ac895b483b49959042931 (patch) | |
tree | f5a9d5ee7f9092a860e28415287de0cb0ac37cf4 /src/libstore | |
parent | 44f6e6de77dd318800775d594b1f33cffa2be9a5 (diff) |
* In `nix-store --export', abort if the contents of a path has
changed. This prevents corrupt paths from spreading to other machines. Note that checking the hash is cheap because we're hashing anyway (because of the --sign feature).
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/local-store.cc | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/src/libstore/local-store.cc b/src/libstore/local-store.cc index c7232056f8ed..ff7196644182 100644 --- a/src/libstore/local-store.cc +++ b/src/libstore/local-store.cc @@ -930,16 +930,19 @@ struct HashAndWriteSink : Sink { Sink & writeSink; HashSink hashSink; - bool hashing; HashAndWriteSink(Sink & writeSink) : writeSink(writeSink), hashSink(htSHA256) { - hashing = true; } virtual void operator () (const unsigned char * data, unsigned int len) { writeSink(data, len); - if (hashing) hashSink(data, len); + hashSink(data, len); + } + Hash currentHash() + { + HashSink hashSinkClone(hashSink); + return hashSinkClone.finish(); } }; @@ -970,6 +973,15 @@ void LocalStore::exportPath(const Path & path, bool sign, dumpPath(path, hashAndWriteSink); + /* Refuse to export paths that have changed. This prevents + filesystem corruption from spreading to other machines. */ + Hash hash = hashAndWriteSink.currentHash(); + Hash storedHash = queryPathHash(path); + if (hash != storedHash) + throw Error(format("hash of path `%1%' has changed from `%2%' to `%3%'!") % path + % printHash(storedHash) % printHash(hash)); + printMsg(lvlError, printHash(hash)); + writeInt(EXPORT_MAGIC, hashAndWriteSink); writeString(path, hashAndWriteSink); @@ -982,9 +994,8 @@ void LocalStore::exportPath(const Path & path, bool sign, writeString(deriver, hashAndWriteSink); if (sign) { - Hash hash = hashAndWriteSink.hashSink.finish(); - hashAndWriteSink.hashing = false; - + Hash hash = hashAndWriteSink.currentHash(); + writeInt(1, hashAndWriteSink); Path tmpDir = createTempDir(); |