mirror of
https://github.com/vgough/encfs.git
synced 2024-11-22 16:03:34 +01:00
Merge pull request #125 from ossobv/wjd-refuse_descent_into_own_mountpoint
Perform checks to ensure that we're not descending into ourself.
This commit is contained in:
commit
a461d88cc3
@ -254,13 +254,9 @@ DirNode::DirNode(EncFS_Context *_ctx, const string &sourceDir,
|
|||||||
Lock _lock(mutex);
|
Lock _lock(mutex);
|
||||||
|
|
||||||
ctx = _ctx;
|
ctx = _ctx;
|
||||||
rootDir = sourceDir;
|
rootDir = sourceDir; // .. and fsConfig->opts->mountPoint have trailing slash
|
||||||
fsConfig = _config;
|
fsConfig = _config;
|
||||||
|
|
||||||
// make sure rootDir ends in '/', so that we can form a path by appending
|
|
||||||
// the rest..
|
|
||||||
if (rootDir[rootDir.length() - 1] != '/') rootDir.append(1, '/');
|
|
||||||
|
|
||||||
naming = fsConfig->nameCoding;
|
naming = fsConfig->nameCoding;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -277,6 +273,27 @@ string DirNode::rootDirectory() {
|
|||||||
return string(rootDir, 0, rootDir.length() - 1);
|
return string(rootDir, 0, rootDir.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DirNode::touchesMountpoint( const char *realPath ) const {
|
||||||
|
const string &mountPoint = fsConfig->opts->mountPoint;
|
||||||
|
// compare mountPoint up to the leading slash.
|
||||||
|
// examples:
|
||||||
|
// mountPoint = /home/user/Junk/experiment/
|
||||||
|
// realPath = /home/user/Junk/experiment
|
||||||
|
// realPath = /home/user/Junk/experiment/abc
|
||||||
|
const ssize_t len = mountPoint.length() - 1;
|
||||||
|
|
||||||
|
if (mountPoint.compare(0, len, realPath, len) == 0) {
|
||||||
|
// if next character is a NUL or a slash, then we're referencing our
|
||||||
|
// mount point:
|
||||||
|
// .../experiment => true
|
||||||
|
// .../experiment/... => true
|
||||||
|
// .../experiment2/abc => false
|
||||||
|
return realPath[len] == '\0' || realPath[len] == '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encrypt a plain-text file path to the ciphertext path with the
|
* Encrypt a plain-text file path to the ciphertext path with the
|
||||||
* ciphertext root directory name prefixed.
|
* ciphertext root directory name prefixed.
|
||||||
|
@ -86,6 +86,9 @@ class DirNode {
|
|||||||
// return the path to the root directory
|
// return the path to the root directory
|
||||||
std::string rootDirectory();
|
std::string rootDirectory();
|
||||||
|
|
||||||
|
// recursive lookup check
|
||||||
|
bool touchesMountpoint(const char *realPath) const;
|
||||||
|
|
||||||
// find files
|
// find files
|
||||||
shared_ptr<FileNode> lookupNode(const char *plaintextName,
|
shared_ptr<FileNode> lookupNode(const char *plaintextName,
|
||||||
const char *requestor);
|
const char *requestor);
|
||||||
|
@ -69,6 +69,7 @@ enum ConfigMode { Config_Prompt, Config_Standard, Config_Paranoia };
|
|||||||
*/
|
*/
|
||||||
struct EncFS_Opts {
|
struct EncFS_Opts {
|
||||||
std::string rootDir;
|
std::string rootDir;
|
||||||
|
std::string mountPoint; // where to make filesystem visible
|
||||||
bool createIfNotFound; // create filesystem if not found
|
bool createIfNotFound; // create filesystem if not found
|
||||||
bool idleTracking; // turn on idle monitoring of filesystem
|
bool idleTracking; // turn on idle monitoring of filesystem
|
||||||
bool mountOnDemand; // mounting on-demand
|
bool mountOnDemand; // mounting on-demand
|
||||||
|
@ -139,6 +139,14 @@ static int withFileNode(const char *opName, const char *path,
|
|||||||
|
|
||||||
rAssert(fnode.get() != NULL);
|
rAssert(fnode.get() != NULL);
|
||||||
rLog(Info, "%s %s", opName, fnode->cipherName());
|
rLog(Info, "%s %s", opName, fnode->cipherName());
|
||||||
|
|
||||||
|
// check that we're not recursing into the mount point itself
|
||||||
|
if (FSRoot->touchesMountpoint(fnode->cipherName())) {
|
||||||
|
rInfo("%s error: Tried to touch mountpoint: '%s'",
|
||||||
|
opName, fnode->cipherName());
|
||||||
|
return res; // still -EIO
|
||||||
|
}
|
||||||
|
|
||||||
res = op(fnode.get());
|
res = op(fnode.get());
|
||||||
|
|
||||||
if (res < 0) rInfo("%s error: %s", opName, strerror(-res));
|
if (res < 0) rInfo("%s error: %s", opName, strerror(-res));
|
||||||
|
@ -74,7 +74,6 @@ const int MaxFuseArgs = 32;
|
|||||||
* derived from the arguments
|
* derived from the arguments
|
||||||
*/
|
*/
|
||||||
struct EncFS_Args {
|
struct EncFS_Args {
|
||||||
string mountPoint; // where to make filesystem visible
|
|
||||||
bool isDaemon; // true == spawn in background, log to syslog
|
bool isDaemon; // true == spawn in background, log to syslog
|
||||||
bool isThreaded; // true == threaded
|
bool isThreaded; // true == threaded
|
||||||
bool isVerbose; // false == only enable warning/error messages
|
bool isVerbose; // false == only enable warning/error messages
|
||||||
@ -373,8 +372,10 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
// we should have at least 2 arguments left over - the source directory and
|
// we should have at least 2 arguments left over - the source directory and
|
||||||
// the mount point.
|
// the mount point.
|
||||||
if (optind + 2 <= argc) {
|
if (optind + 2 <= argc) {
|
||||||
|
// both rootDir and mountPoint are assumed to be slash terminated in the
|
||||||
|
// rest of the code.
|
||||||
out->opts->rootDir = slashTerminate(argv[optind++]);
|
out->opts->rootDir = slashTerminate(argv[optind++]);
|
||||||
out->mountPoint = argv[optind++];
|
out->opts->mountPoint = slashTerminate(argv[optind++]);
|
||||||
} else {
|
} else {
|
||||||
// no mount point specified
|
// no mount point specified
|
||||||
rWarning(_("Missing one or more arguments, aborting."));
|
rWarning(_("Missing one or more arguments, aborting."));
|
||||||
@ -420,7 +421,7 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
}
|
}
|
||||||
|
|
||||||
// sanity check
|
// sanity check
|
||||||
if (out->isDaemon && (!isAbsolutePath(out->mountPoint.c_str()) ||
|
if (out->isDaemon && (!isAbsolutePath(out->opts->mountPoint.c_str()) ||
|
||||||
!isAbsolutePath(out->opts->rootDir.c_str()))) {
|
!isAbsolutePath(out->opts->rootDir.c_str()))) {
|
||||||
cerr <<
|
cerr <<
|
||||||
// xgroup(usage)
|
// xgroup(usage)
|
||||||
@ -431,7 +432,7 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
|
|
||||||
// the raw directory may not be a subdirectory of the mount point.
|
// the raw directory may not be a subdirectory of the mount point.
|
||||||
{
|
{
|
||||||
string testMountPoint = slashTerminate(out->mountPoint);
|
string testMountPoint = out->opts->mountPoint;
|
||||||
string testRootDir = out->opts->rootDir.substr(0, testMountPoint.length());
|
string testRootDir = out->opts->rootDir.substr(0, testMountPoint.length());
|
||||||
|
|
||||||
if (testMountPoint == testRootDir) {
|
if (testMountPoint == testRootDir) {
|
||||||
@ -464,15 +465,15 @@ static bool processArgs(int argc, char *argv[],
|
|||||||
rWarning(_("Unable to locate root directory, aborting."));
|
rWarning(_("Unable to locate root directory, aborting."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!isDirectory(out->mountPoint.c_str()) &&
|
if (!isDirectory(out->opts->mountPoint.c_str()) &&
|
||||||
!userAllowMkdir(out->opts->annotate ? 2 : 0, out->mountPoint.c_str(),
|
!userAllowMkdir(out->opts->annotate ? 2 : 0, out->opts->mountPoint.c_str(),
|
||||||
0700)) {
|
0700)) {
|
||||||
rWarning(_("Unable to locate mount point, aborting."));
|
rWarning(_("Unable to locate mount point, aborting."));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill in mount path for fuse
|
// fill in mount path for fuse
|
||||||
out->fuseArgv[1] = out->mountPoint.c_str();
|
out->fuseArgv[1] = out->opts->mountPoint.c_str();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -767,7 +768,7 @@ static bool unmountFS(EncFS_Context *ctx) {
|
|||||||
shared_ptr<EncFS_Args> arg = ctx->args;
|
shared_ptr<EncFS_Args> arg = ctx->args;
|
||||||
if (arg->opts->mountOnDemand) {
|
if (arg->opts->mountOnDemand) {
|
||||||
rDebug("Detaching filesystem %s due to inactivity",
|
rDebug("Detaching filesystem %s due to inactivity",
|
||||||
arg->mountPoint.c_str());
|
arg->opts->mountPoint.c_str());
|
||||||
|
|
||||||
ctx->setRoot(shared_ptr<DirNode>());
|
ctx->setRoot(shared_ptr<DirNode>());
|
||||||
return false;
|
return false;
|
||||||
@ -775,8 +776,8 @@ static bool unmountFS(EncFS_Context *ctx) {
|
|||||||
// Time to unmount!
|
// Time to unmount!
|
||||||
// xgroup(diag)
|
// xgroup(diag)
|
||||||
rWarning(_("Unmounting filesystem %s due to inactivity"),
|
rWarning(_("Unmounting filesystem %s due to inactivity"),
|
||||||
arg->mountPoint.c_str());
|
arg->opts->mountPoint.c_str());
|
||||||
fuse_unmount(arg->mountPoint.c_str());
|
fuse_unmount(arg->opts->mountPoint.c_str());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user