Browse Source

opportunistically change ugid

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

2
src/access.cpp

@ -76,7 +76,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _access(config.access,

2
src/chmod.cpp

@ -76,7 +76,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _chmod(config.chmod,

2
src/chown.cpp

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

5
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);
}
@ -95,7 +96,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _create(config.getattr,

2
src/getattr.cpp

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

2
src/getxattr.cpp

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

2
src/ioctl.cpp

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

5
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);
}
@ -112,7 +113,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _link(config.getattr,

2
src/listxattr.cpp

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

5
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);
}
@ -96,7 +97,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mkdir(config.getattr,

5
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);
}
@ -99,7 +100,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _mknod(config.getattr,

2
src/open.cpp

@ -78,7 +78,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _open(config.open,

2
src/readdir.cpp

@ -98,7 +98,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readdir(config.srcmounts,

2
src/readlink.cpp

@ -77,7 +77,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _readlink(config.readlink,

2
src/removexattr.cpp

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

5
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);
}
@ -115,7 +116,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _rename(config.getattr,

2
src/rmdir.cpp

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

2
src/setxattr.cpp

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

2
src/statfs.cpp

@ -126,7 +126,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _statfs(config.srcmounts,

2
src/symlink.cpp

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

2
src/truncate.cpp

@ -79,7 +79,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _truncate(config.truncate,

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

89
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()
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
if(initialized == false)
{
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);
currentuid = ::syscall(SYS_geteuid);
currentgid = ::syscall(SYS_getegid);
initialized = true;
}
}
~SetResetGuard()
static
void
set(const uid_t newuid,
const gid_t newgid)
{
if(currentuid != newuid || currentgid != newgid)
{
if(olduid != newuid)
::syscall(SYS_setreuid,-1,olduid);
if(oldgid != newgid)
::syscall(SYS_setregid,-1,oldgid);
::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
{
SetReset(const uid_t newuid,
const gid_t newgid)
{
init();
olduid = currentuid;
oldgid = currentgid;
set(newuid,newgid);
}
~SetReset()
{
set(olduid,oldgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
};
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

54
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)
{
SetResetGuard(const uid_t _newuid,
}
struct SetReset
{
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)
{}
};
}
}

70
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)
if(initialized == false)
{
pthread_getugid_np(&olduid,&oldgid);
newuid = _newuid;
newgid = _newgid;
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;
}
}
~SetResetGuard()
struct SetReset
{
if(newgid != oldgid || newuid != olduid)
pthread_setugid_np(newuid,newgid);
SetReset(const uid_t newuid,
const gid_t newgid)
{
init();
olduid = currentuid;
oldgid = currentgid;
set(newuid,newgid);
}
~SetReset()
{
set(olduid,oldgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
};
struct SuperUser
{
SuperUser()
: setreset(0,0)
{}
SetReset setreset;
};
struct Set
{
Set(const uid_t newuid,
const gid_t newgid)
{
init();
set(newuid,newgid);
}
};
}
}

2
src/unlink.cpp

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

2
src/utimens.cpp

@ -79,7 +79,7 @@ namespace mergerfs
{
const fuse_context *fc = fuse_get_context();
const Config &config = Config::get(fc);
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const ugid::Set ugid(fc->uid,fc->gid);
const rwlock::ReadGuard readlock(&config.srcmountslock);
return _utimens(config.utimens,

Loading…
Cancel
Save