Do a sanity check when mounting the file system and fail if the root blob is not available.

This commit is contained in:
Sebastian Messmer 2016-02-19 02:10:10 +01:00
parent f134946089
commit d00e097954
5 changed files with 28 additions and 10 deletions

View File

@ -18,6 +18,7 @@
#include <boost/filesystem.hpp>
#include <gitversion/version.h>
#include <cryfs/filesystem/CryDir.h>
#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<OnDiskBlockStore>(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<CryDir>(*_rootDir);
if (rootDir == none) {
throw std::runtime_error("Base directory blob doesn't contain a directory");
}
(*rootDir)->children(); // Load children
}
optional<unique_ref<CallAfterTimeout>> Cli::_createIdleCallback(optional<double> minutes, function<void()> callback) {
if (minutes == none) {
return none;

View File

@ -9,6 +9,7 @@
#include <cpp-utils/io/Console.h>
#include <cpp-utils/random/RandomGenerator.h>
#include <cpp-utils/network/HttpClient.h>
#include <cryfs/filesystem/CryDevice.h>
#include "CallAfterTimeout.h"
namespace cryfs {
@ -36,6 +37,7 @@ namespace cryfs {
std::shared_ptr<cpputils::TempFile> _checkDirWriteable(const boost::filesystem::path &dir, const std::string &name);
void _checkDirReadable(const boost::filesystem::path &dir, std::shared_ptr<cpputils::TempFile> tempfile, const std::string &name);
boost::optional<cpputils::unique_ref<CallAfterTimeout>> _createIdleCallback(boost::optional<double> minutes, std::function<void()> callback);
void _sanityCheckFilesystem(CryDevice *device);
cpputils::RandomGenerator &_keyGenerator;
cpputils::SCryptSettings _scryptSettings;

View File

@ -74,7 +74,7 @@ optional<unique_ref<fspp::Node>> 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<unique_ref<fspp::Node>>(make_unique_ref<CryDir>(this, none, _rootKey));
}
auto parent = LoadDirBlob(path.parent_path());
@ -165,7 +165,7 @@ unique_ref<SymlinkBlobRef> CryDevice::CreateSymlinkBlob(const bf::path &target)
unique_ref<FsBlobRef> 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<FsBlobRef> 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));

View File

@ -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<FsBlobRef> 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);
}

View File

@ -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);