Skip to content

Commit

Permalink
Merge pull request #125 from ossobv/wjd-refuse_descent_into_own_mount…
Browse files Browse the repository at this point in the history
…point

Perform checks to ensure that we're not descending into ourself.
  • Loading branch information
vgough committed Nov 15, 2015
2 parents 2d3780b + 07fb5b8 commit a461d88
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 15 deletions.
27 changes: 22 additions & 5 deletions encfs/DirNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,13 +254,9 @@ DirNode::DirNode(EncFS_Context *_ctx, const string &sourceDir,
Lock _lock(mutex);

ctx = _ctx;
rootDir = sourceDir;
rootDir = sourceDir; // .. and fsConfig->opts->mountPoint have trailing slash
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;
}

Expand All @@ -277,6 +273,27 @@ string DirNode::rootDirectory() {
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
* ciphertext root directory name prefixed.
Expand Down
3 changes: 3 additions & 0 deletions encfs/DirNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,9 @@ class DirNode {
// return the path to the root directory
std::string rootDirectory();

// recursive lookup check
bool touchesMountpoint(const char *realPath) const;

// find files
shared_ptr<FileNode> lookupNode(const char *plaintextName,
const char *requestor);
Expand Down
1 change: 1 addition & 0 deletions encfs/FileUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ enum ConfigMode { Config_Prompt, Config_Standard, Config_Paranoia };
*/
struct EncFS_Opts {
std::string rootDir;
std::string mountPoint; // where to make filesystem visible
bool createIfNotFound; // create filesystem if not found
bool idleTracking; // turn on idle monitoring of filesystem
bool mountOnDemand; // mounting on-demand
Expand Down
8 changes: 8 additions & 0 deletions encfs/encfs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,14 @@ static int withFileNode(const char *opName, const char *path,

rAssert(fnode.get() != NULL);
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());

if (res < 0) rInfo("%s error: %s", opName, strerror(-res));
Expand Down
21 changes: 11 additions & 10 deletions encfs/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ const int MaxFuseArgs = 32;
* derived from the arguments
*/
struct EncFS_Args {
string mountPoint; // where to make filesystem visible
bool isDaemon; // true == spawn in background, log to syslog
bool isThreaded; // true == threaded
bool isVerbose; // false == only enable warning/error messages
Expand Down Expand Up @@ -373,8 +372,10 @@ static bool processArgs(int argc, char *argv[],
// we should have at least 2 arguments left over - the source directory and
// the mount point.
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->mountPoint = argv[optind++];
out->opts->mountPoint = slashTerminate(argv[optind++]);
} else {
// no mount point specified
rWarning(_("Missing one or more arguments, aborting."));
Expand Down Expand Up @@ -420,7 +421,7 @@ static bool processArgs(int argc, char *argv[],
}

// 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()))) {
cerr <<
// xgroup(usage)
Expand All @@ -431,7 +432,7 @@ static bool processArgs(int argc, char *argv[],

// 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());

if (testMountPoint == testRootDir) {
Expand Down Expand Up @@ -464,15 +465,15 @@ static bool processArgs(int argc, char *argv[],
rWarning(_("Unable to locate root directory, aborting."));
return false;
}
if (!isDirectory(out->mountPoint.c_str()) &&
!userAllowMkdir(out->opts->annotate ? 2 : 0, out->mountPoint.c_str(),
if (!isDirectory(out->opts->mountPoint.c_str()) &&
!userAllowMkdir(out->opts->annotate ? 2 : 0, out->opts->mountPoint.c_str(),
0700)) {
rWarning(_("Unable to locate mount point, aborting."));
return false;
}

// fill in mount path for fuse
out->fuseArgv[1] = out->mountPoint.c_str();
out->fuseArgv[1] = out->opts->mountPoint.c_str();

return true;
}
Expand Down Expand Up @@ -767,16 +768,16 @@ static bool unmountFS(EncFS_Context *ctx) {
shared_ptr<EncFS_Args> arg = ctx->args;
if (arg->opts->mountOnDemand) {
rDebug("Detaching filesystem %s due to inactivity",
arg->mountPoint.c_str());
arg->opts->mountPoint.c_str());

ctx->setRoot(shared_ptr<DirNode>());
return false;
} else {
// Time to unmount!
// xgroup(diag)
rWarning(_("Unmounting filesystem %s due to inactivity"),
arg->mountPoint.c_str());
fuse_unmount(arg->mountPoint.c_str());
arg->opts->mountPoint.c_str());
fuse_unmount(arg->opts->mountPoint.c_str());
return true;
}
}

0 comments on commit a461d88

Please sign in to comment.