In integrity violations, use individual messages saying which check exactly failed.
This commit is contained in:
parent
f066b45954
commit
1c654305a8
@ -10,15 +10,20 @@ namespace blockstore {
|
||||
|
||||
class IntegrityViolationError final : public std::exception {
|
||||
public:
|
||||
IntegrityViolationError(const std::string &reason)
|
||||
: _reason("Integrity violation: " + reason) {
|
||||
}
|
||||
|
||||
const char *what() const throw() override {
|
||||
return _reason.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
// Constructor is private to make sure that only VersionCountingBlockStore can throw this exception.
|
||||
// This is because VersionCountingBlockStore wants to know about integrity violations and
|
||||
// block all further file system access if it happens.
|
||||
IntegrityViolationError(const std::string &reason)
|
||||
: _reason("Integrity violation: " + reason) {
|
||||
}
|
||||
friend class VersionCountingBlockStore;
|
||||
|
||||
std::string _reason;
|
||||
};
|
||||
|
||||
|
@ -114,7 +114,7 @@ inline void VersionCountingBlock::_checkVersion() {
|
||||
uint32_t lastClientId = _readClientId();
|
||||
uint64_t version = _readVersion();
|
||||
if(!_blockStore->knownBlockVersions()->checkAndUpdateVersion(lastClientId, key(), version)) {
|
||||
_blockStore->integrityViolationDetected();
|
||||
_blockStore->integrityViolationDetected("The block version number is too low. Did an attacker try to roll back the block or to re-introduce a deleted block?");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,7 @@ using cpputils::make_unique_ref;
|
||||
using cpputils::Data;
|
||||
using boost::none;
|
||||
using boost::optional;
|
||||
using std::string;
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
namespace blockstore {
|
||||
@ -35,7 +36,7 @@ namespace blockstore {
|
||||
auto block = _baseBlockStore->load(key);
|
||||
if (block == boost::none) {
|
||||
if (_missingBlockIsIntegrityViolation && _knownBlockVersions.blockShouldExist(key)) {
|
||||
integrityViolationDetected();
|
||||
integrityViolationDetected("A block that should exist wasn't found. Did an attacker delete it?");
|
||||
}
|
||||
return boost::none;
|
||||
}
|
||||
@ -52,9 +53,9 @@ namespace blockstore {
|
||||
}
|
||||
}
|
||||
|
||||
void VersionCountingBlockStore::integrityViolationDetected() {
|
||||
void VersionCountingBlockStore::integrityViolationDetected(const string &reason) const {
|
||||
_integrityViolationDetected = true;
|
||||
throw IntegrityViolationError("A block that should exist wasn't found. Did an attacker delete it?");
|
||||
throw IntegrityViolationError(reason);
|
||||
}
|
||||
|
||||
void VersionCountingBlockStore::remove(unique_ref<Block> block) {
|
||||
@ -93,7 +94,7 @@ namespace blockstore {
|
||||
}
|
||||
});
|
||||
if (!existingBlocks.empty()) {
|
||||
throw IntegrityViolationError("A block that should have existed wasn't found.");
|
||||
integrityViolationDetected("A block that should have existed wasn't found.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ public:
|
||||
uint64_t blockSizeFromPhysicalBlockSize(uint64_t blockSize) const override;
|
||||
void forEachBlock(std::function<void (const Key &)> callback) const override;
|
||||
|
||||
void integrityViolationDetected();
|
||||
void integrityViolationDetected(const std::string &reason) const;
|
||||
KnownBlockVersions *knownBlockVersions();
|
||||
|
||||
#ifndef CRYFS_NO_COMPATIBILITY
|
||||
@ -35,7 +35,7 @@ private:
|
||||
cpputils::unique_ref<BlockStore> _baseBlockStore;
|
||||
KnownBlockVersions _knownBlockVersions;
|
||||
const bool _missingBlockIsIntegrityViolation;
|
||||
bool _integrityViolationDetected;
|
||||
mutable bool _integrityViolationDetected;
|
||||
|
||||
void _checkNoPastIntegrityViolations();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user