Merge pull request #182 from vgough/issue181

Fix issue 181 by reverting the responsible commits
This commit is contained in:
Valient Gough 2016-06-29 20:52:55 -07:00 committed by GitHub
commit 4d952b74d8
3 changed files with 50 additions and 12 deletions

View File

@ -75,6 +75,32 @@ RawFileIO::~RawFileIO() {
Interface RawFileIO::interface() const { return RawFileIO_iface; }
/*
Workaround for opening a file for write when permissions don't allow.
Since the kernel has already checked permissions, we can assume it is ok to
provide access. So force it by changing permissions temporarily. Should
be called with a lock around it so that there won't be a race condition
with calls to lstat picking up the wrong permissions.
This works around the problem described in https://github.com/vgough/encfs/issues/181
Without this, "umask 0777 ; echo foo > bar" fails.
*/
static int open_readonly_workaround(const char *path, int flags) {
int fd = -1;
struct stat stbuf;
memset(&stbuf, 0, sizeof(struct stat));
if (lstat(path, &stbuf) != -1) {
// make sure user has read/write permission..
chmod(path, stbuf.st_mode | 0600);
fd = ::open(path, flags);
chmod(path, stbuf.st_mode);
} else {
RLOG(INFO) << "can't stat file " << path;
}
return fd;
}
/*
We shouldn't have to support all possible open flags, so untaint the flags
argument by only taking ones we understand and accept.
@ -107,6 +133,11 @@ int RawFileIO::open(int flags) {
VLOG(1) << "open file with flags " << finalFlags << ", result = " << newFd;
if ((newFd == -1) && (errno == EACCES)) {
VLOG(1) << "using readonly workaround for open";
newFd = open_readonly_workaround(name.c_str(), finalFlags);
}
if (newFd >= 0) {
if (oldfd >= 0) {
RLOG(ERROR) << "leaking FD?: oldfd = " << oldfd << ", fd = " << fd

View File

@ -405,17 +405,14 @@ static bool processArgs(int argc, char *argv[],
PUSHARG("-o");
PUSHARG("use_ino");
// "default_permissions" comes with a performance cost. Only enable
// it if makes sense.
for (int i = 0; i < out->fuseArgc; i++) {
if (out->fuseArgv[i] == NULL) {
continue;
} else if (strcmp(out->fuseArgv[i], "allow_other") == 0) {
PUSHARG("-o");
PUSHARG("default_permissions");
break;
}
}
// "default_permissions" comes with a performance cost, and only makes
// sense if "allow_other"" is used.
// But it works around the issues "open_readonly_workaround" causes,
// so enable it unconditionally.
// See https://github.com/vgough/encfs/issues/181 and
// https://github.com/vgough/encfs/issues/112 for more info.
PUSHARG("-o");
PUSHARG("default_permissions");
#if defined(__APPLE__)
// With OSXFuse, the 'local' flag selects a local filesystem mount icon in

View File

@ -2,7 +2,7 @@
# Test EncFS normal and paranoid mode
use Test::More tests => 102;
use Test::More tests => 104;
use File::Path;
use File::Copy;
use File::Temp;
@ -46,6 +46,7 @@ sub runTests
&renames;
&internalModification;
&grow;
&umask0777;
&cleanup;
}
@ -324,3 +325,12 @@ sub cleanup
ok( ! -d $workingDir, "working dir removed");
}
# Test that we can create and write to a a file even if umask is set to 0777
# Regression test for bug https://github.com/vgough/encfs/issues/181
sub umask0777
{
my $old = umask(0777);
ok(open(my $fh, "+>$crypt/umask0777"), "open with umask 0777");
close($fh);
umask($old);
}