Browse Source

opportunistically change ugid

pull/98/head
Antonio SJ Musumeci 10 years ago
parent
commit
b74162c574
  1. 8
      src/access.cpp
  2. 8
      src/chmod.cpp
  3. 8
      src/chown.cpp
  4. 11
      src/create.cpp
  5. 4
      src/getattr.cpp
  6. 4
      src/getxattr.cpp
  7. 8
      src/ioctl.cpp
  8. 11
      src/link.cpp
  9. 4
      src/listxattr.cpp
  10. 11
      src/mkdir.cpp
  11. 11
      src/mknod.cpp
  12. 8
      src/open.cpp
  13. 8
      src/readdir.cpp
  14. 8
      src/readlink.cpp
  15. 4
      src/removexattr.cpp
  16. 11
      src/rename.cpp
  17. 8
      src/rmdir.cpp
  18. 4
      src/setxattr.cpp
  19. 8
      src/statfs.cpp
  20. 8
      src/symlink.cpp
  21. 8
      src/truncate.cpp
  22. 11
      src/ugid.cpp
  23. 93
      src/ugid_linux.hpp
  24. 56
      src/ugid_mutex.hpp
  25. 76
      src/ugid_osx.hpp
  26. 8
      src/unlink.cpp
  27. 8
      src/utimens.cpp

8
src/access.cpp

@ -74,10 +74,10 @@ namespace mergerfs
access(const char *fusepath,
int mask)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _access(config.access,
config.srcmounts,

8
src/chmod.cpp

@ -74,10 +74,10 @@ namespace mergerfs
chmod(const char *fusepath,
mode_t mode)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chmod(config.chmod,
config.srcmounts,

8
src/chown.cpp

@ -78,10 +78,10 @@ namespace mergerfs
uid_t uid,
gid_t gid)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chown(config.chown,
config.srcmounts,

11
src/create.cpp

@ -40,6 +40,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs::ugid;
static
int
@ -69,7 +70,7 @@ _create(Policy::Func::Search searchFunc,
if(createpath[0] != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const SuperUser superuser;
fs::clonepath(existingpath[0],createpath[0],dirname);
}
@ -93,10 +94,10 @@ namespace mergerfs
mode_t mode,
fuse_file_info *fileinfo)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _create(config.getattr,
config.create,

4
src/getattr.cpp

@ -100,8 +100,8 @@ namespace mergerfs
if(fusepath == config.controlfile)
return _getattr_controlfile(*st);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _getattr(config.getattr,
config.srcmounts,

4
src/getxattr.cpp

@ -254,8 +254,8 @@ namespace mergerfs
buf,
count);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _getxattr(config.getxattr,
config.srcmounts,

8
src/ioctl.cpp

@ -98,10 +98,10 @@ _ioctl_dir(const string &fusepath,
const int cmd,
void *data)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _ioctl_dir_base(config.getattr,
config.srcmounts,

11
src/link.cpp

@ -38,6 +38,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs::ugid;
static
int
@ -64,7 +65,7 @@ _single_link(Policy::Func::Search searchFunc,
return -1;
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const SuperUser superuser;
fs::clonepath(foundpath[0],base,newpathdir);
}
@ -110,10 +111,10 @@ namespace mergerfs
link(const char *from,
const char *to)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _link(config.getattr,
config.link,

4
src/listxattr.cpp

@ -115,8 +115,8 @@ namespace mergerfs
if(fusepath == config.controlfile)
return _listxattr_controlfile(list,size);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _listxattr(config.listxattr,
config.srcmounts,

11
src/mkdir.cpp

@ -39,6 +39,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs::ugid;
static
int
@ -72,7 +73,7 @@ _mkdir(Policy::Func::Search searchFunc,
if(createpath != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const SuperUser superuser;
fs::clonepath(existingpath[0],createpath,dirname);
}
@ -94,10 +95,10 @@ namespace mergerfs
mkdir(const char *fusepath,
mode_t mode)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mkdir(config.getattr,
config.mkdir,

11
src/mknod.cpp

@ -41,6 +41,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs::ugid;
static
int
@ -74,7 +75,7 @@ _mknod(Policy::Func::Search searchFunc,
if(createpath != existingpath[0])
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const SuperUser superuser;
fs::clonepath(existingpath[0],createpath,dirname);
}
@ -97,10 +98,10 @@ namespace mergerfs
mode_t mode,
dev_t rdev)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mknod(config.getattr,
config.mknod,

8
src/open.cpp

@ -76,10 +76,10 @@ namespace mergerfs
open(const char *fusepath,
fuse_file_info *fileinfo)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _open(config.open,
config.srcmounts,

8
src/readdir.cpp

@ -96,10 +96,10 @@ namespace mergerfs
off_t offset,
fuse_file_info *fi)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readdir(config.srcmounts,
fusepath,

8
src/readlink.cpp

@ -75,10 +75,10 @@ namespace mergerfs
char *buf,
size_t size)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readlink(config.readlink,
config.srcmounts,

4
src/removexattr.cpp

@ -87,8 +87,8 @@ namespace mergerfs
if(fusepath == config.controlfile)
return -ENOTSUP;
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _removexattr(config.removexattr,
config.srcmounts,

11
src/rename.cpp

@ -39,6 +39,7 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs::ugid;
static
int
@ -64,7 +65,7 @@ _single_rename(Policy::Func::Search searchFunc,
return -1;
{
const mergerfs::ugid::SetResetGuard ugid(0,0);
const SuperUser superuser;
fs::clonepath(newpathdir[0],oldbasepath,dirname);
}
@ -113,10 +114,10 @@ namespace mergerfs
rename(const char *oldpath,
const char *newpath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _rename(config.getattr,
config.rename,

8
src/rmdir.cpp

@ -73,10 +73,10 @@ namespace mergerfs
int
rmdir(const char *fusepath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readguard(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readguard(&config.srcmountslock);
return _rmdir(config.rmdir,
config.srcmounts,

4
src/setxattr.cpp

@ -321,8 +321,8 @@ namespace mergerfs
flags);
}
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _setxattr(config.setxattr,
config.srcmounts,

8
src/statfs.cpp

@ -124,10 +124,10 @@ namespace mergerfs
statfs(const char *fusepath,
struct statvfs *stat)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _statfs(config.srcmounts,
*stat);

8
src/symlink.cpp

@ -77,10 +77,10 @@ namespace mergerfs
symlink(const char *oldpath,
const char *newpath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _symlink(config.symlink,
config.srcmounts,

8
src/truncate.cpp

@ -77,10 +77,10 @@ namespace mergerfs
truncate(const char *fusepath,
off_t size)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _truncate(config.truncate,
config.srcmounts,

11
src/ugid.cpp

@ -25,7 +25,16 @@
#include "ugid.hpp"
#if defined __linux__
__thread uid_t mergerfs::ugid::currentuid = 0;
__thread gid_t mergerfs::ugid::currentgid = 0;
__thread bool mergerfs::ugid::initialized = false;
#elif defined __APPLE__
__thread uid_t mergerfs::ugid::currentuid = 0;
__thread gid_t mergerfs::ugid::currentgid = 0;
__thread bool mergerfs::ugid::initialized = false;
#else
pthread_mutex_t mergerfs::ugid::SetResetGuard::lock = PTHREAD_MUTEX_INITIALIZER;
uid_t mergerfs::ugid::currentuid = 0;
gid_t mergerfs::ugid::currentgid = 0;
bool mergerfs::ugid::initialized = false;
pthread_mutex_t mergerfs::ugid::lock = PTHREAD_MUTEX_INITIALIZER;
#endif

93
src/ugid_linux.hpp

@ -27,38 +27,89 @@
#include <unistd.h>
#include <sys/syscall.h>
#define ROOT 0
#define UNCHANGED -1
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
extern __thread uid_t currentuid;
extern __thread gid_t currentgid;
extern __thread bool initialized;
static
void
init()
{
if(initialized == false)
{
currentuid = ::syscall(SYS_geteuid);
currentgid = ::syscall(SYS_getegid);
initialized = true;
}
}
static
void
set(const uid_t newuid,
const gid_t newgid)
{
if(currentuid != newuid || currentgid != newgid)
{
::syscall(SYS_setreuid,UNCHANGED,ROOT);
if(currentgid != newgid)
::syscall(SYS_setregid,UNCHANGED,newgid);
if(newuid != ROOT)
::syscall(SYS_setreuid,UNCHANGED,newuid);
currentuid = newuid;
currentgid = newgid;
}
}
struct SetReset
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
SetReset(const uid_t newuid,
const gid_t newgid)
{
olduid = ::syscall(SYS_geteuid);
oldgid = ::syscall(SYS_getegid);
newuid = _newuid;
newgid = _newgid;
if(newgid != oldgid)
::syscall(SYS_setregid,-1,newgid);
if(newuid != olduid)
::syscall(SYS_setreuid,-1,newuid);
init();
olduid = currentuid;
oldgid = currentgid;
set(newuid,newgid);
}
~SetResetGuard()
~SetReset()
{
if(olduid != newuid)
::syscall(SYS_setreuid,-1,olduid);
if(oldgid != newgid)
::syscall(SYS_setregid,-1,oldgid);
set(olduid,oldgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
uid_t olduid;
gid_t oldgid;
};
struct SuperUser
{
SuperUser()
: setreset(0,0)
{}
const SetReset setreset;
};
struct Set
{
Set(const uid_t newuid,
const gid_t newgid)
{
init();
set(newuid,newgid);
}
};
}
}
#undef ROOT
#undef UNCHANGED

56
src/ugid_mutex.hpp

@ -31,38 +31,68 @@ namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
extern uid_t currentuid;
extern gid_t currentgid;
extern bool initialized;
extern pthread_mutex_t lock;
static
void
init()
{
if(initialized == false)
{
currentuid = ::geteuid();
currentgid = ::getegid();
initialized = true;
}
}
static
void
set(const uid_t newuid,
const gid_t newgid)
{
}
struct SetReset
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
SetReset(const uid_t _newuid,
const gid_t _newgid)
{
pthread_mutex_lock(&lock);
init();
olduid = ::geteuid();
oldgid = ::getegid();
newuid = _newuid;
newgid = _newgid;
olduid = currentuid;
oldgid = currentgid;
if(newgid != oldgid)
seteuid(0);
if(_newgid != oldgid)
setegid(newgid);
if(newuid != olduid)
if(_newuid != olduid)
seteuid(newuid);
}
~SetResetGuard()
{
if(olduid != newuid)
seteuid(newuid);
seteuid(olduid);
if(oldgid != newgid)
setegid(newgid);
setegid(oldgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
};
static pthread_mutex_t lock;
struct SuperUser : public SetReset
{
SuperUser()
: UnlockedSetReset(0,0)
{}
};
}
}

76
src/ugid_osx.hpp

@ -29,29 +29,75 @@ namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
extern __thread uid_t currentuid;
extern __thread gid_t currentgid;
extern __thread bool initialized;
static
void
init()
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
{
pthread_getugid_np(&olduid,&oldgid);
newuid = _newuid;
newgid = _newgid;
if(initialized == false)
{
pthread_getugid_np(&currentuid,&currentgid);
initialized = true;
}
}
if(newgid != oldgid || newuid != olduid)
static
void
set(const uid_t newuid,
const gid_t newgid)
{
if(currentuid != newuid || currentgid != newgid)
{
pthread_setugid_np(KAUTH_UID_NONE,KAUTH_GID_NONE);
pthread_setugid_np(newuid,newgid);
currentuid = newuid;
currentgid = newgid;
}
}
struct SetReset
{
SetReset(const uid_t newuid,
const gid_t newgid)
{
init();
olduid = currentuid;
oldgid = currentgid;
set(newuid,newgid);
}
~SetResetGuard()
~SetReset()
{
if(newgid != oldgid || newuid != olduid)
pthread_setugid_np(newuid,newgid);
set(olduid,oldgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
uid_t olduid;
gid_t oldgid;
};
struct SuperUser
{
SuperUser()
: setreset(0,0)
{}
SetReset setreset;
};
struct Set
{
Set(const uid_t newuid,
const gid_t newgid)
{
init();
set(newuid,newgid);
}
};
}
}

8
src/unlink.cpp

@ -74,10 +74,10 @@ namespace mergerfs
int
unlink(const char *fusepath)
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _unlink(config.unlink,
config.srcmounts,

8
src/utimens.cpp

@ -77,10 +77,10 @@ namespace mergerfs
utimens(const char *fusepath,
const timespec ts[2])
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _utimens(config.utimens,
config.srcmounts,

Loading…
Cancel
Save