diff --git a/src/cryfs/cli/Cli.cpp b/src/cryfs/cli/Cli.cpp index 1944c259..dc52a6bb 100644 --- a/src/cryfs/cli/Cli.cpp +++ b/src/cryfs/cli/Cli.cpp @@ -18,6 +18,7 @@ #include #include +#include #include "VersionChecker.h" @@ -60,6 +61,7 @@ using boost::chrono::duration; using boost::chrono::duration_cast; using boost::chrono::minutes; using boost::chrono::milliseconds; +using cpputils::dynamic_pointer_move; //TODO Delete a large file in parallel possible? Takes a long time right now... //TODO Improve parallelity. @@ -197,6 +199,7 @@ namespace cryfs { auto blockStore = make_unique_ref(options.baseDir()); auto config = _loadOrCreateConfig(options); CryDevice device(std::move(config), std::move(blockStore)); + _sanityCheckFilesystem(&device); fspp::FilesystemImpl fsimpl(&device); fspp::fuse::Fuse fuse(&fsimpl); @@ -223,6 +226,19 @@ namespace cryfs { } } + void Cli::_sanityCheckFilesystem(CryDevice *device) { + //Try to list contents of base directory + auto _rootDir = device->Load("/"); // this might throw an exception if the root blob doesn't exist + if (_rootDir == none) { + throw std::runtime_error("Couldn't find root blob"); + } + auto rootDir = dynamic_pointer_move(*_rootDir); + if (rootDir == none) { + throw std::runtime_error("Base directory blob doesn't contain a directory"); + } + (*rootDir)->children(); // Load children + } + optional> Cli::_createIdleCallback(optional minutes, function callback) { if (minutes == none) { return none; diff --git a/src/cryfs/cli/Cli.h b/src/cryfs/cli/Cli.h index ec90db78..6aed5ec6 100644 --- a/src/cryfs/cli/Cli.h +++ b/src/cryfs/cli/Cli.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "CallAfterTimeout.h" namespace cryfs { @@ -36,6 +37,7 @@ namespace cryfs { std::shared_ptr _checkDirWriteable(const boost::filesystem::path &dir, const std::string &name); void _checkDirReadable(const boost::filesystem::path &dir, std::shared_ptr tempfile, const std::string &name); boost::optional> _createIdleCallback(boost::optional minutes, std::function callback); + void _sanityCheckFilesystem(CryDevice *device); cpputils::RandomGenerator &_keyGenerator; cpputils::SCryptSettings _scryptSettings; diff --git a/src/cryfs/filesystem/CryDevice.cpp b/src/cryfs/filesystem/CryDevice.cpp index 33edd67c..4b7b53c5 100644 --- a/src/cryfs/filesystem/CryDevice.cpp +++ b/src/cryfs/filesystem/CryDevice.cpp @@ -74,7 +74,7 @@ optional> CryDevice::Load(const bf::path &path) { callFsActionCallbacks(); if (path.parent_path().empty()) { - //We are asked to load the root directory '/'. + //We are asked to load the base directory '/'. return optional>(make_unique_ref(this, none, _rootKey)); } auto parent = LoadDirBlob(path.parent_path()); @@ -165,7 +165,7 @@ unique_ref CryDevice::CreateSymlinkBlob(const bf::path &target) unique_ref CryDevice::LoadBlob(const blockstore::Key &key) { auto blob = _fsBlobStore->load(key); if (blob == none) { - LOG(ERROR) << "Could not load blob " << key.ToString() << ". Is the root directory accessible?"; + LOG(ERROR) << "Could not load blob " << key.ToString() << ". Is the base directory accessible?"; throw FuseErrnoException(EIO); } return std::move(*blob); @@ -174,7 +174,7 @@ unique_ref CryDevice::LoadBlob(const blockstore::Key &key) { void CryDevice::RemoveBlob(const blockstore::Key &key) { auto blob = _fsBlobStore->load(key); if (blob == none) { - LOG(ERROR) << "Could not load blob " << key.ToString() << ". Is the root directory accessible?"; + LOG(ERROR) << "Could not load blob " << key.ToString() << ". Is the base directory accessible?"; throw FuseErrnoException(EIO); } _fsBlobStore->remove(std::move(*blob)); diff --git a/src/cryfs/filesystem/CryNode.cpp b/src/cryfs/filesystem/CryNode.cpp index 129cad77..70ee278f 100644 --- a/src/cryfs/filesystem/CryNode.cpp +++ b/src/cryfs/filesystem/CryNode.cpp @@ -44,7 +44,7 @@ void CryNode::access(int mask) const { void CryNode::rename(const bf::path &to) { device()->callFsActionCallbacks(); if (_parent == none) { - //We are the root direcory. + //We are the base direcory. //TODO What should we do? throw FuseErrnoException(EIO); } @@ -67,7 +67,7 @@ void CryNode::rename(const bf::path &to) { void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) { device()->callFsActionCallbacks(); if (_parent == none) { - //We are the root direcory. + //We are the base direcory. //TODO What should we do? throw FuseErrnoException(EIO); } @@ -77,7 +77,7 @@ void CryNode::utimens(timespec lastAccessTime, timespec lastModificationTime) { void CryNode::removeNode() { //TODO Instead of all these if-else and having _parent being an optional, we could also introduce a CryRootDir which inherits from fspp::Dir. if (_parent == none) { - //We are the root direcory. + //We are the base direcory. //TODO What should we do? throw FuseErrnoException(EIO); } @@ -100,7 +100,7 @@ unique_ref CryNode::LoadBlob() const { void CryNode::stat(struct ::stat *result) const { device()->callFsActionCallbacks(); if(_parent == none) { - //We are the root directory. + //We are the base directory. //TODO What should we do? result->st_uid = getuid(); result->st_gid = getgid(); @@ -114,7 +114,7 @@ void CryNode::stat(struct ::stat *result) const { void CryNode::chmod(mode_t mode) { device()->callFsActionCallbacks(); if (_parent == none) { - //We are the root direcory. + //We are the base direcory. //TODO What should we do? throw FuseErrnoException(EIO); } @@ -124,7 +124,7 @@ void CryNode::chmod(mode_t mode) { void CryNode::chown(uid_t uid, gid_t gid) { device()->callFsActionCallbacks(); if (_parent == none) { - //We are the root direcory. + //We are the base direcory. //TODO What should we do? throw FuseErrnoException(EIO); } diff --git a/src/fspp/fuse/Fuse.cpp b/src/fspp/fuse/Fuse.cpp index 2343fa4b..d22b53bb 100644 --- a/src/fspp/fuse/Fuse.cpp +++ b/src/fspp/fuse/Fuse.cpp @@ -275,7 +275,7 @@ int Fuse::fgetattr(const bf::path &path, struct stat *stbuf, fuse_file_info *fil // On FreeBSD, trying to do anything with the mountpoint ends up // opening it, and then using the FD for an fgetattr. So in the // special case of a path of "/", I need to do a getattr on the - // underlying root directory instead of doing the fgetattr(). + // underlying base directory instead of doing the fgetattr(). // TODO Check if necessary if (path.native() == "/") { return getattr(path, stbuf);