mirror of
https://github.com/vgough/encfs.git
synced 2025-01-14 01:48:30 +01:00
Implement --nocache
Disable block cache (in EncFS) and stat cache (in kernel). This is needed if the backing files may be modified behind the back of EncFS (for example, when you mount an encrypted filesystem exported by encfs --reverse). The reverse grow tests fail when this option is not passed to the decrypting mount.
This commit is contained in:
parent
9f9e30a73f
commit
dee3f628e3
@ -27,6 +27,8 @@
|
||||
|
||||
#include "i18n.h"
|
||||
|
||||
#include "FileUtils.h"
|
||||
|
||||
template <typename Type>
|
||||
inline Type min(Type A, Type B) {
|
||||
return (B < A) ? B : A;
|
||||
@ -41,6 +43,7 @@ BlockFileIO::BlockFileIO(int blockSize, const FSConfigPtr &cfg)
|
||||
: _blockSize(blockSize), _allowHoles(cfg->config->allowHoles) {
|
||||
rAssert(_blockSize > 1);
|
||||
_cache.data = new unsigned char[_blockSize];
|
||||
_noCache = cfg->opts->noCache;
|
||||
}
|
||||
|
||||
BlockFileIO::~BlockFileIO() {
|
||||
@ -61,8 +64,11 @@ ssize_t BlockFileIO::cacheReadOneBlock(const IORequest &req) const {
|
||||
|
||||
/* we can satisfy the request even if _cache.dataLen is too short, because
|
||||
* we always request a full block during reads. This just means we are
|
||||
* in the last block of a file, which may be smaller than the blocksize. */
|
||||
if ((req.offset == _cache.offset) && (_cache.dataLen != 0)) {
|
||||
* in the last block of a file, which may be smaller than the blocksize.
|
||||
* For reverse encryption, the cache must not be used at all, because
|
||||
* the lower file may have changed behind our back. */
|
||||
if ( (_noCache == false) && (req.offset == _cache.offset) &&
|
||||
(_cache.dataLen != 0)) {
|
||||
// satisfy request from cache
|
||||
int len = req.dataLen;
|
||||
if (_cache.dataLen < len) len = _cache.dataLen; // Don't read past EOF
|
||||
|
@ -57,6 +57,7 @@ class BlockFileIO : public FileIO {
|
||||
|
||||
int _blockSize;
|
||||
bool _allowHoles;
|
||||
bool _noCache;
|
||||
|
||||
// cache last block for speed...
|
||||
mutable IORequest _cache;
|
||||
|
@ -76,6 +76,11 @@ struct EncFS_Opts {
|
||||
|
||||
bool reverseEncryption; // Reverse encryption
|
||||
|
||||
bool noCache; /* Disable block cache (in EncFS) and stat cache (in kernel).
|
||||
* This is needed if the backing files may be modified
|
||||
* behind the back of EncFS (for example, in reverse mode).
|
||||
* See main.cpp for a longer explaination. */
|
||||
|
||||
ConfigMode configMode;
|
||||
|
||||
EncFS_Opts() {
|
||||
@ -90,6 +95,7 @@ struct EncFS_Opts {
|
||||
ownerCreate = false;
|
||||
reverseEncryption = false;
|
||||
configMode = Config_Prompt;
|
||||
noCache = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -212,6 +212,7 @@ static bool processArgs(int argc, char *argv[],
|
||||
// {"single-thread", 0, 0, 's'}, // single-threaded mode
|
||||
{"stdinpass", 0, 0, 'S'}, // read password from stdin
|
||||
{"annotate", 0, 0, 513}, // Print annotation lines to stderr
|
||||
{"nocache", 0, 0, 514}, // disable caching
|
||||
{"verbose", 0, 0, 'v'}, // verbose mode
|
||||
{"version", 0, 0, 'V'}, // version
|
||||
{"reverse", 0, 0, 'r'}, // reverse encryption
|
||||
@ -272,24 +273,32 @@ static bool processArgs(int argc, char *argv[],
|
||||
case 'D':
|
||||
out->opts->forceDecode = true;
|
||||
break;
|
||||
/* By default, the kernel caches file metadata for one second.
|
||||
* This is fine for EncFS' normal mode, but for --reverse, this
|
||||
* means that the encrypted view will be up to one second out of
|
||||
* date.
|
||||
* Quoting Goswin von Brederlow:
|
||||
* "Caching only works correctly if you implement a disk based
|
||||
* filesystem, one where only the fuse process can alter
|
||||
* metadata and all access goes only through fuse. Any overlay
|
||||
* filesystem where something can change the underlying
|
||||
* filesystem without going through fuse can run into
|
||||
* inconsistencies."
|
||||
* Enabling reverse automatically enables noCache. */
|
||||
case 'r':
|
||||
out->opts->reverseEncryption = true;
|
||||
/* By default, the kernel caches file metadata for one second.
|
||||
* This is fine for EncFS' normal mode, but for --reverse, this
|
||||
* means that the encrypted view will be up to one second out of
|
||||
* date.
|
||||
* Quoting Goswin von Brederlow:
|
||||
* "Caching only works correctly if you implement a disk based
|
||||
* filesystem, one where only the fuse process can alter
|
||||
* metadata and all access goes only through fuse. Any overlay
|
||||
* filesystem where something can change the underlying
|
||||
* filesystem without going through fuse can run into
|
||||
* inconsistencies."
|
||||
* Disable caching so the encrypted view stays consistent with
|
||||
* the backing files. */
|
||||
PUSHARG("-oattr_timeout=0"); // Causes reverse grow tests to fail
|
||||
// because stale stat() data is returned
|
||||
PUSHARG("-oentry_timeout=0"); // Fallout unknown, disabling for safety
|
||||
case 514:
|
||||
/* Disable EncFS block cache
|
||||
* Causes reverse grow tests to fail because short reads
|
||||
* are returned */
|
||||
out->opts->noCache = true;
|
||||
/* Disable kernel stat() cache
|
||||
* Causes reverse grow tests to fail because stale stat() data
|
||||
* is returned */
|
||||
PUSHARG("-oattr_timeout=0");
|
||||
/* Disable kernel dentry cache
|
||||
* Fallout unknown, disabling for safety */
|
||||
PUSHARG("-oentry_timeout=0");
|
||||
break;
|
||||
case 'm':
|
||||
out->opts->mountOnDemand = true;
|
||||
|
@ -48,7 +48,7 @@ sub mount
|
||||
ok(waitForFile("$plain/.encfs6.xml"), "plain .encfs6.xml exists") or BAIL_OUT("'$plain/.encfs6.xml'");
|
||||
my $e = encName(".encfs6.xml");
|
||||
ok(waitForFile("$ciphertext/$e"), "encrypted .encfs6.xml exists") or BAIL_OUT("'$ciphertext/$e'");
|
||||
system("ENCFS6_CONFIG=$plain/.encfs6.xml ./encfs/encfs -o attr_timeout=0 --extpass=\"echo test\" $ciphertext $decrypted");
|
||||
system("ENCFS6_CONFIG=$plain/.encfs6.xml ./encfs/encfs --nocache --extpass=\"echo test\" $ciphertext $decrypted");
|
||||
ok(waitForFile("$decrypted/.encfs6.xml"), "decrypted .encfs6.xml exists") or BAIL_OUT("'$decrypted/.encfs6.xml'");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user