Return error code when integrity violation is encountered

This commit is contained in:
Sebastian Messmer 2018-12-18 21:40:03 -08:00
parent 5d77a82c7f
commit 944cb6c3c5
3 changed files with 16 additions and 9 deletions

View File

@ -226,18 +226,19 @@ namespace cryfs {
auto blockStore = make_unique_ref<OnDiskBlockStore2>(options.baseDir());
auto config = _loadOrCreateConfig(options, localStateDir);
unique_ptr<fspp::fuse::Fuse> fuse = nullptr;
auto onIntegrityViolation = [&fuse] () {
bool stoppedBecauseOfIntegrityViolation = false;
auto onIntegrityViolation = [&fuse, &stoppedBecauseOfIntegrityViolation] () {
if (fuse.get() != nullptr) {
LOG(ERR, "Integrity violation detected. Unmounting.");
stoppedBecauseOfIntegrityViolation = true;
fuse->stop();
} else {
// the file system isn't initialized yet, i.e. we failed in the initial steps when
// Usually on an integrity violation, the file system is unmounted.
// Here, the file system isn't initialized yet, i.e. we failed in the initial steps when
// setting up _device before running initFilesystem.
// We can't unmount a not-mounted file system, but we can make sure it doesn't get mounted.
// Error code is "success" because that's also what is returned if this happens while
// the file system is already mounted - it gets unmounted cleanly.
// TODO Should we reconsider this?
throw CryfsException("Integrity violation detected. Unmounting.", ErrorCode::Success);
throw CryfsException("Integrity violation detected. Unmounting.", ErrorCode::IntegrityViolation);
}
};
const bool missingBlockIsIntegrityViolation = config.configFile.config()->missingBlockIsIntegrityViolation();
@ -268,6 +269,10 @@ namespace cryfs {
<< std::endl;
#endif
fuse->run(options.mountDir(), options.fuseOptions());
if (stoppedBecauseOfIntegrityViolation) {
throw CryfsException("Integrity violation detected. Unmounting.", ErrorCode::IntegrityViolation);
}
} catch (const CryfsException &e) {
throw; // CryfsException is only thrown if setup goes wrong. Throw it through so that we get the correct process exit code.
} catch (const std::exception &e) {

View File

@ -54,6 +54,9 @@ enum class ErrorCode : int {
// A previous run of the file system detected an integrity violation. Preventing access to make sure the user notices. The file system will be accessible again after the user deletes the integrity state file.
IntegrityViolationOnPreviousRun = 24,
// An integrity violation was detected and the file system unmounted to make sure the user notices.
IntegrityViolation = 25
};
inline int exitCode(ErrorCode code) {

View File

@ -130,7 +130,7 @@ TEST_F(CliTest_IntegrityCheck, givenFilesystemWithRolledBackBasedir_whenMounting
recursive_copy(backup.path() / "basedir", basedir);
// error code is success because it unmounts normally
EXPECT_RUN_ERROR(args, "Integrity violation detected. Unmounting.", ErrorCode::Success, [&] {
EXPECT_RUN_ERROR(args, "Integrity violation detected. Unmounting.", ErrorCode::IntegrityViolation, [&] {
EXPECT_FALSE(readingFileIsSuccessful(mountdir / "myfile"));
});
@ -151,8 +151,7 @@ TEST_F(CliTest_IntegrityCheck, whenRollingBackBasedirWhileMounted_thenUnmounts)
TempDir backup;
recursive_copy(basedir, backup.path() / "basedir");
// error code is success because it unmounts normally
EXPECT_RUN_ERROR(args, "Integrity violation detected. Unmounting.", ErrorCode::Success, [&] {
EXPECT_RUN_ERROR(args, "Integrity violation detected. Unmounting.", ErrorCode::IntegrityViolation, [&] {
// modify the file system contents
writeFile(mountdir / "myfile", "hello world 2");
ASSERT(readingFileIsSuccessful(mountdir / "myfile"), ""); // just to make sure reading usually works