Do a sanity check when mounting the file system and fail if the root blob is not available.
This commit is contained in:
parent
f134946089
commit
d00e097954
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user