Browse Source

stop clonepath at base directory. fixes #467

pull/471/head
Antonio SJ Musumeci 6 years ago
parent
commit
f48c16d162
  1. 21
      src/create.cpp
  2. 29
      src/fs_clonepath.cpp
  3. 7
      src/fs_clonepath.hpp
  4. 24
      src/link.cpp
  5. 23
      src/mkdir.cpp
  6. 23
      src/mknod.cpp
  7. 59
      src/rename.cpp
  8. 24
      src/symlink.cpp
  9. 15
      src/ugid.cpp
  10. 9
      src/ugid.hpp
  11. 112
      src/ugid_linux.hpp
  12. 17
      src/ugid_linux.icpp
  13. 119
      src/ugid_rwlock.hpp
  14. 29
      src/ugid_rwlock.icpp

21
src/create.cpp

@ -34,7 +34,6 @@ using std::vector;
using namespace mergerfs;
static
inline
int
_create_core(const string &fullpath,
mode_t mode,
@ -49,10 +48,8 @@ _create_core(const string &fullpath,
static
int
_create_core(const string &existingpath,
const string &createpath,
_create_core(const string &createpath,
const char *fusepath,
const char *fusedirpath,
const mode_t mode,
const mode_t umask,
const int flags,
@ -61,14 +58,6 @@ _create_core(const string &existingpath,
int rv;
string fullpath;
if(createpath != existingpath)
{
const ugid::SetRootGuard ugidGuard;
rv = fs::clonepath(existingpath,createpath,fusedirpath);
if(rv == -1)
return -errno;
}
fs::path::make(&createpath,fusepath,fullpath);
rv = _create_core(fullpath,mode,umask,flags);
@ -111,8 +100,12 @@ _create(Policy::Func::Search searchFunc,
if(rv == -1)
return -errno;
return _create_core(*existingpaths[0],*createpaths[0],
fusepath,fusedirpathcstr,
rv = fs::clonepath_as_root(*existingpaths[0],*createpaths[0],fusedirpath);
if(rv == -1)
return -errno;
return _create_core(*createpaths[0],
fusepath,
mode,umask,flags,fh);
}

29
src/fs_clonepath.cpp

@ -26,6 +26,7 @@
#include "fs_clonepath.hpp"
#include "fs_path.hpp"
#include "fs_xattr.hpp"
#include "ugid.hpp"
using std::string;
@ -59,6 +60,9 @@ namespace fs
string frompath;
string dirname;
if((relative == NULL) || (relative[0] == '\0'))
return 0;
dirname = relative;
fs::path::dirname(dirname);
if(!dirname.empty())
@ -114,4 +118,29 @@ namespace fs
{
return fs::clonepath(from,to,relative.c_str());
}
int
clonepath_as_root(const string &from,
const string &to,
const char *relative)
{
if((relative == NULL) || (relative[0] == '\0'))
return 0;
if(from == to)
return 0;
{
const ugid::SetRootGuard ugidGuard;
return fs::clonepath(from,to,relative);
}
}
int
clonepath_as_root(const std::string &from,
const std::string &to,
const std::string &relative)
{
return fs::clonepath_as_root(from,to,relative.c_str());
}
}

7
src/fs_clonepath.hpp

@ -26,4 +26,11 @@ namespace fs
int clonepath(const std::string &from,
const std::string &to,
const std::string &relative);
int clonepath_as_root(const std::string &from,
const std::string &to,
const char *relative);
int clonepath_as_root(const std::string &from,
const std::string &to,
const std::string &relative);
}

24
src/link.cpp

@ -39,21 +39,12 @@ _link_create_path_core(const string &oldbasepath,
const string &newbasepath,
const char *oldfusepath,
const char *newfusepath,
const string &newfusedirpath,
const int error)
{
int rv;
string oldfullpath;
string newfullpath;
if(oldbasepath != newbasepath)
{
const ugid::SetRootGuard ugidGuard;
rv = fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
if(rv == -1)
return errno;
}
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
fs::path::make(&oldbasepath,newfusepath,newfullpath);
@ -70,15 +61,19 @@ _link_create_path_loop(const vector<const string*> &oldbasepaths,
const char *newfusepath,
const string &newfusedirpath)
{
int rv;
int error;
error = -1;
for(size_t i = 0, ei = oldbasepaths.size(); i != ei; i++)
{
error = _link_create_path_core(*oldbasepaths[i],newbasepath,
oldfusepath,newfusepath,
newfusedirpath,
error);
rv = fs::clonepath_as_root(newbasepath,*oldbasepaths[i],newfusedirpath);
if(rv == -1)
error = error::calc(rv,error,errno);
else
error = _link_create_path_core(*oldbasepaths[i],newbasepath,
oldfusepath,newfusepath,
error);
}
return -error;
@ -143,8 +138,7 @@ _clonepath_if_would_create(Policy::Func::Search searchFunc,
if(rv == -1)
return -1;
const ugid::SetRootGuard ugidGuard;
return fs::clonepath(*newbasepath[0],oldbasepath,newfusedirpathcstr);
return fs::clonepath_as_root(*newbasepath[0],oldbasepath,newfusedirpathcstr);
}
static

23
src/mkdir.cpp

@ -34,7 +34,6 @@ using std::vector;
using namespace mergerfs;
static
inline
int
_mkdir_core(const string &fullpath,
mode_t mode,
@ -48,10 +47,8 @@ _mkdir_core(const string &fullpath,
static
int
_mkdir_loop_core(const string &existingpath,
const string &createpath,
_mkdir_loop_core(const string &createpath,
const char *fusepath,
const char *fusedirpath,
const mode_t mode,
const mode_t umask,
const int error)
@ -59,14 +56,6 @@ _mkdir_loop_core(const string &existingpath,
int rv;
string fullpath;
if(createpath != existingpath)
{
const ugid::SetRootGuard ugidGuard;
rv = fs::clonepath(existingpath,createpath,fusedirpath);
if(rv == -1)
return errno;
}
fs::path::make(&createpath,fusepath,fullpath);
rv = _mkdir_core(fullpath,mode,umask);
@ -83,13 +72,19 @@ _mkdir_loop(const string &existingpath,
const mode_t mode,
const mode_t umask)
{
int rv;
int error;
error = -1;
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
{
error = _mkdir_loop_core(existingpath,*createpaths[i],
fusepath,fusedirpath,mode,umask,error);
rv = fs::clonepath_as_root(existingpath,*createpaths[i],fusedirpath);
if(rv == -1)
error = error::calc(rv,error,errno);
else
error = _mkdir_loop_core(*createpaths[i],
fusepath,
mode,umask,error);
}
return -error;

23
src/mknod.cpp

@ -49,10 +49,8 @@ _mknod_core(const string &fullpath,
static
int
_mknod_loop_core(const string &existingpath,
const string &createpath,
_mknod_loop_core(const string &createpath,
const char *fusepath,
const char *fusedirpath,
const mode_t mode,
const mode_t umask,
const dev_t dev,
@ -61,14 +59,6 @@ _mknod_loop_core(const string &existingpath,
int rv;
string fullpath;
if(createpath != existingpath)
{
const ugid::SetRootGuard ugidGuard;
rv = fs::clonepath(existingpath,createpath,fusedirpath);
if(rv == -1)
return -1;
}
fs::path::make(&createpath,fusepath,fullpath);
rv = _mknod_core(fullpath,mode,umask,dev);
@ -86,14 +76,19 @@ _mknod_loop(const string &existingpath,
const mode_t umask,
const dev_t dev)
{
int rv;
int error;
error = -1;
for(size_t i = 0, ei = createpaths.size(); i != ei; i++)
{
error = _mknod_loop_core(existingpath,*createpaths[i],
fusepath,fusedirpath,
mode,umask,dev,error);
rv = fs::clonepath_as_root(existingpath,*createpaths[i],fusedirpath);
if(rv == -1)
error = error::calc(rv,error,errno);
else
error = _mknod_loop_core(*createpaths[i],
fusepath,
mode,umask,dev,error);
}
return -error;

59
src/rename.cpp

@ -27,7 +27,6 @@
#include "fs_path.hpp"
#include "rv.hpp"
#include "rwlock.hpp"
#include "success_fail.hpp"
#include "ugid.hpp"
using std::string;
@ -57,27 +56,6 @@ _remove(const vector<string> &toremove)
fs::remove(toremove[i]);
}
static
int
_rename(const std::string &oldbasepath,
const std::string &oldfullpath,
const std::string &newbasepath,
const std::string &newfusedirpath,
const std::string &newfullpath)
{
int rv;
if(oldbasepath != newbasepath)
{
const ugid::SetRootGuard guard;
rv = fs::clonepath(newbasepath,oldbasepath,newfusedirpath);
if(rv == -1)
return -1;
}
return fs::rename(oldfullpath,newfullpath);
}
static
void
_rename_create_path_core(const vector<const string*> &oldbasepaths,
@ -94,21 +72,26 @@ _rename_create_path_core(const vector<const string*> &oldbasepaths,
string oldfullpath;
string newfullpath;
fs::path::make(&oldbasepath,newfusepath,newfullpath);
ismember = member(oldbasepaths,oldbasepath);
if(ismember)
{
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
rv = fs::clonepath_as_root(newbasepath,oldbasepath,newfusedirpath);
if(rv != -1)
{
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
fs::path::make(&oldbasepath,newfusepath,newfullpath);
rv = fs::rename(oldfullpath,newfullpath);
}
rv = _rename(oldbasepath,oldfullpath,
newbasepath,newfusedirpath,newfullpath);
error = error::calc(rv,error,errno);
if(RENAME_FAILED(rv))
if(rv == -1)
tounlink.push_back(oldfullpath);
}
else
{
fs::path::make(&oldbasepath,newfusepath,newfullpath);
tounlink.push_back(newfullpath);
}
}
@ -138,7 +121,7 @@ _rename_create_path(Policy::Func::Search searchFunc,
if(POLICY_FAILED(rv))
return -errno;
error = RENAME_FAIL;
error = -1;
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
{
const string &oldbasepath = srcmounts[i];
@ -150,7 +133,8 @@ _rename_create_path(Policy::Func::Search searchFunc,
error,toremove);
}
if(RENAME_SUCCEEDED(error))
if(error == 0)
_remove(toremove);
return -error;
@ -169,12 +153,9 @@ _clonepath(Policy::Func::Search searchFunc,
rv = searchFunc(srcmounts,fusedirpath.c_str(),minfreespace,srcbasepath);
if(POLICY_FAILED(rv))
return rv;
return -errno;
{
const ugid::SetRootGuard ugidGuard;
fs::clonepath(*srcbasepath[0],dstbasepath,fusedirpath);
}
fs::clonepath_as_root(*srcbasepath[0],dstbasepath,fusedirpath);
return POLICY_SUCCESS;
}
@ -232,7 +213,7 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc,
fs::path::make(&oldbasepath,oldfusepath,oldfullpath);
rv = fs::rename(oldfullpath,newfullpath);
if(RENAME_FAILED_WITH(rv,ENOENT))
if((rv == -1) && (errno == ENOENT))
{
rv = _clonepath_if_would_create(searchFunc,createFunc,
srcmounts,minfreespace,
@ -242,7 +223,7 @@ _rename_preserve_path_core(Policy::Func::Search searchFunc,
}
error = error::calc(rv,error,errno);
if(RENAME_FAILED(rv))
if(rv == -1)
toremove.push_back(oldfullpath);
}
else
@ -270,7 +251,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
if(POLICY_FAILED(rv))
return -errno;
error = RENAME_FAIL;
error = -1;
for(size_t i = 0, ei = srcmounts.size(); i != ei; i++)
{
const string &oldbasepath = srcmounts[i];
@ -282,7 +263,7 @@ _rename_preserve_path(Policy::Func::Search searchFunc,
error,toremove);
}
if(RENAME_SUCCEEDED(error))
if(error == 0)
_remove(toremove);
return -error;

24
src/symlink.cpp

@ -36,24 +36,14 @@ using namespace mergerfs;
static
int
_symlink_loop_core(const string &existingpath,
const string &newbasepath,
_symlink_loop_core(const string &newbasepath,
const char *oldpath,
const char *newpath,
const char *newdirpath,
const int error)
{
int rv;
string fullnewpath;
if(newbasepath != existingpath)
{
const ugid::SetRootGuard ugidGuard;
rv = fs::clonepath(existingpath,newbasepath,newdirpath);
if(rv == -1)
return -1;
}
fs::path::make(&newbasepath,newpath,fullnewpath);
rv = fs::symlink(oldpath,fullnewpath);
@ -69,14 +59,20 @@ _symlink_loop(const string &existingpath,
const char *newpath,
const char *newdirpath)
{
int rv;
int error;
error = -1;
for(size_t i = 0, ei = newbasepaths.size(); i != ei; i++)
{
error = _symlink_loop_core(existingpath,*newbasepaths[i],
oldpath,newpath,newdirpath,
error);
rv = fs::clonepath_as_root(existingpath,*newbasepaths[i],newdirpath);
if(rv == -1)
error = error::calc(rv,error,errno);
else
error = _symlink_loop_core(*newbasepaths[i],
oldpath,
newpath,
error);
}
return -error;

15
src/ugid.cpp

@ -22,17 +22,14 @@
#include "ugid_rwlock.icpp"
#endif
namespace mergerfs
namespace ugid
{
namespace ugid
void
initgroups(const uid_t uid,
const gid_t gid)
{
void
initgroups(const uid_t uid,
const gid_t gid)
{
static __thread gid_t_cache cache = {0};
static __thread gid_t_cache cache = {0};
cache.initgroups(uid,gid);
}
cache.initgroups(uid,gid);
}
}

9
src/ugid.hpp

@ -21,13 +21,10 @@
#include <vector>
namespace mergerfs
namespace ugid
{
namespace ugid
{
void init();
void initgroups(const uid_t uid, const gid_t gid);
}
void init();
void initgroups(const uid_t uid, const gid_t gid);
}
#if defined __linux__ and UGID_USE_RWLOCK == 0

112
src/ugid_linux.hpp

@ -51,68 +51,64 @@
#define GETEGID() (::syscall(SYS_getegid))
#endif
namespace mergerfs
namespace ugid
{
namespace ugid
{
extern __thread uid_t currentuid;
extern __thread gid_t currentgid;
extern __thread bool initialized;
extern __thread uid_t currentuid;
extern __thread gid_t currentgid;
extern __thread bool initialized;
struct Set
struct Set
{
Set(const uid_t newuid,
const gid_t newgid)
{
Set(const uid_t newuid,
const gid_t newgid)
{
if(!initialized)
{
currentuid = GETEUID();
currentgid = GETEGID();
initialized = true;
}
if(newuid == currentuid && newgid == currentgid)
return;
if(currentuid != 0)
{
SETREUID(-1,0);
SETREGID(-1,0);
}
if(newgid)
{
SETREGID(-1,newgid);
initgroups(newuid,newgid);
}
if(newuid)
SETREUID(-1,newuid);
currentuid = newuid;
currentgid = newgid;
}
};
struct SetRootGuard
if(!initialized)
{
currentuid = GETEUID();
currentgid = GETEGID();
initialized = true;
}
if(newuid == currentuid && newgid == currentgid)
return;
if(currentuid != 0)
{
SETREUID(-1,0);
SETREGID(-1,0);
}
if(newgid)
{
SETREGID(-1,newgid);
initgroups(newuid,newgid);
}
if(newuid)
SETREUID(-1,newuid);
currentuid = newuid;
currentgid = newgid;
}
};
struct SetRootGuard
{
SetRootGuard() :
prevuid(currentuid),
prevgid(currentgid)
{
SetRootGuard() :
prevuid(currentuid),
prevgid(currentgid)
{
Set(0,0);
}
~SetRootGuard()
{
Set(prevuid,prevgid);
}
const uid_t prevuid;
const gid_t prevgid;
};
}
Set(0,0);
}
~SetRootGuard()
{
Set(prevuid,prevgid);
}
const uid_t prevuid;
const gid_t prevgid;
};
}
#undef SETREUID

17
src/ugid_linux.icpp

@ -21,17 +21,14 @@
#include <vector>
namespace mergerfs
namespace ugid
{
namespace ugid
{
__thread uid_t currentuid = 0;
__thread gid_t currentgid = 0;
__thread bool initialized = false;
__thread uid_t currentuid = 0;
__thread gid_t currentgid = 0;
__thread bool initialized = false;
void
init()
{
}
void
init()
{
}
}

119
src/ugid_rwlock.hpp

@ -21,81 +21,78 @@
#include <sys/types.h>
#include <unistd.h>
namespace mergerfs
namespace ugid
{
namespace ugid
extern uid_t currentuid;
extern gid_t currentgid;
extern pthread_rwlock_t rwlock;
static
void
ugid_set(const uid_t newuid,
const gid_t newgid)
{
extern uid_t currentuid;
extern gid_t currentgid;
extern pthread_rwlock_t rwlock;
static
void
ugid_set(const uid_t newuid,
const gid_t newgid)
{
pthread_rwlock_rdlock(&rwlock);
pthread_rwlock_rdlock(&rwlock);
if(newuid == currentuid && newgid == currentgid)
return;
if(newuid == currentuid && newgid == currentgid)
return;
pthread_rwlock_unlock(&rwlock);
pthread_rwlock_wrlock(&rwlock);
pthread_rwlock_unlock(&rwlock);
pthread_rwlock_wrlock(&rwlock);
if(newuid == currentuid && newgid == currentgid)
return;
if(newuid == currentuid && newgid == currentgid)
return;
if(currentuid != 0)
{
::seteuid(0);
::setegid(0);
}
if(currentuid != 0)
{
::seteuid(0);
::setegid(0);
}
if(newgid)
{
::setegid(newgid);
initgroups(newuid,newgid);
}
if(newgid)
{
::setegid(newgid);
initgroups(newuid,newgid);
}
if(newuid)
::seteuid(newuid);
if(newuid)
::seteuid(newuid);
currentuid = newuid;
currentgid = newgid;
}
currentuid = newuid;
currentgid = newgid;
}
struct Set
struct Set
{
Set(const uid_t newuid,
const gid_t newgid)
{
Set(const uid_t newuid,
const gid_t newgid)
{
ugid_set(newuid,newgid);
}
ugid_set(newuid,newgid);
}
~Set()
{
pthread_rwlock_unlock(&rwlock);
}
};
~Set()
{
pthread_rwlock_unlock(&rwlock);
}
};
struct SetRootGuard
struct SetRootGuard
{
SetRootGuard() :
prevuid(currentuid),
prevgid(currentgid)
{
SetRootGuard() :
prevuid(currentuid),
prevgid(currentgid)
{
pthread_rwlock_unlock(&rwlock);
ugid_set(0,0);
}
pthread_rwlock_unlock(&rwlock);
ugid_set(0,0);
}
~SetRootGuard()
{
pthread_rwlock_unlock(&rwlock);
ugid_set(prevuid,prevgid);
}
~SetRootGuard()
{
pthread_rwlock_unlock(&rwlock);
ugid_set(prevuid,prevgid);
}
const uid_t prevuid;
const gid_t prevgid;
};
}
const uid_t prevuid;
const gid_t prevgid;
};
}

29
src/ugid_rwlock.icpp

@ -21,28 +21,25 @@
#include <vector>
namespace mergerfs
namespace ugid
{
namespace ugid
{
uid_t currentuid;
gid_t currentgid;
pthread_rwlock_t rwlock;
uid_t currentuid;
gid_t currentgid;
pthread_rwlock_t rwlock;
void
init()
{
pthread_rwlockattr_t attr;
void
init()
{
pthread_rwlockattr_t attr;
pthread_rwlockattr_init(&attr);
pthread_rwlockattr_init(&attr);
# if defined PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
pthread_rwlockattr_setkind_np(&attr,PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
# endif
pthread_rwlock_init(&rwlock,&attr);
pthread_rwlock_init(&rwlock,&attr);
currentuid = ::geteuid();
currentgid = ::getegid();
}
currentuid = ::geteuid();
currentgid = ::getegid();
}
}
Loading…
Cancel
Save