Browse Source

platform specific code to deal with sete{u,g}id. closes #17

pull/36/head
Antonio SJ Musumeci 10 years ago
parent
commit
0e12d79659
  1. 8
      Makefile
  2. 3
      src/access.cpp
  3. 5
      src/chmod.cpp
  4. 3
      src/chown.cpp
  5. 7
      src/create.cpp
  6. 6
      src/fallocate.cpp
  7. 6
      src/fgetattr.cpp
  8. 3
      src/flush.cpp
  9. 6
      src/fsync.cpp
  10. 6
      src/ftruncate.cpp
  11. 3
      src/getattr.cpp
  12. 5
      src/getxattr.cpp
  13. 6
      src/ioctl.cpp
  14. 5
      src/link.cpp
  15. 5
      src/listxattr.cpp
  16. 5
      src/mkdir.cpp
  17. 7
      src/mknod.cpp
  18. 3
      src/open.cpp
  19. 3
      src/read.cpp
  20. 3
      src/read_buf.cpp
  21. 3
      src/readdir.cpp
  22. 3
      src/readlink.cpp
  23. 3
      src/release.cpp
  24. 5
      src/removexattr.cpp
  25. 5
      src/rename.cpp
  26. 5
      src/rmdir.cpp
  27. 5
      src/setxattr.cpp
  28. 3
      src/statfs.cpp
  29. 3
      src/symlink.cpp
  30. 3
      src/truncate.cpp
  31. 31
      src/ugid.cpp
  32. 72
      src/ugid.hpp
  33. 64
      src/ugid_linux.hpp
  34. 68
      src/ugid_mutex.hpp
  35. 58
      src/ugid_osx.hpp
  36. 5
      src/unlink.cpp
  37. 11
      src/utimens.cpp
  38. 3
      src/write.cpp
  39. 4
      src/write_buf.cpp

8
Makefile

@ -74,6 +74,14 @@ $(warning "xattr not available: disabling")
CFLAGS += -DWITHOUT_XATTR CFLAGS += -DWITHOUT_XATTR
endif endif
KERNEL = $(shell uname -s)
ifeq ($(KERNEL),Linux)
CFLAGS += -DLINUX
endif
ifeq ($(KERNEL),Darwin)
CFLAGS += -DOSX
endif
all: $(TARGET) all: $(TARGET)
help: help:

3
src/access.cpp

@ -70,8 +70,9 @@ namespace mergerfs
access(const char *fusepath, access(const char *fusepath,
int mask) int mask)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _access(*config.search, return _access(*config.search,

5
src/chmod.cpp

@ -73,8 +73,9 @@ namespace mergerfs
chmod(const char *fusepath, chmod(const char *fusepath,
mode_t mode) mode_t mode)
{ {
ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const struct fuse_context *fc = fuse_get_context();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const config::Config &config = config::get();
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EPERM; return -EPERM;

3
src/chown.cpp

@ -76,8 +76,9 @@ namespace mergerfs
uid_t uid, uid_t uid,
gid_t gid) gid_t gid)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EPERM; return -EPERM;

7
src/create.cpp

@ -100,8 +100,9 @@ namespace mergerfs
mode_t mode, mode_t mode,
struct fuse_file_info *fileinfo) struct fuse_file_info *fileinfo)
{ {
ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _create_controlfile(fileinfo->fh); return _create_controlfile(fileinfo->fh);
@ -110,7 +111,7 @@ namespace mergerfs
*config.create, *config.create,
config.srcmounts, config.srcmounts,
fusepath, fusepath,
mode,
(mode & ~fc->umask),
fileinfo->flags, fileinfo->flags,
fileinfo->fh); fileinfo->fh);
} }

6
src/fallocate.cpp

@ -31,7 +31,6 @@
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include "ugid.hpp"
#include "config.hpp" #include "config.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
@ -77,9 +76,8 @@ namespace mergerfs
off_t len, off_t len,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EINVAL; return -EINVAL;

6
src/fgetattr.cpp

@ -30,7 +30,6 @@
#include <errno.h> #include <errno.h>
#include "config.hpp" #include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
static static
@ -54,9 +53,8 @@ namespace mergerfs
struct stat *st, struct stat *st,
struct fuse_file_info *ffi) struct fuse_file_info *ffi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return (*st = config.controlfilestat,0); return (*st = config.controlfilestat,0);

3
src/flush.cpp

@ -27,7 +27,6 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include "ugid.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
static static
@ -53,8 +52,6 @@ namespace mergerfs
flush(const char *path, flush(const char *path,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
return _flush(((FileInfo*)fi->fh)->fd); return _flush(((FileInfo*)fi->fh)->fd);
} }
} }

6
src/fsync.cpp

@ -35,7 +35,6 @@
#include <errno.h> #include <errno.h>
#include "config.hpp" #include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
static static
@ -61,9 +60,8 @@ namespace mergerfs
int isdatasync, int isdatasync,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return 0; return 0;

6
src/ftruncate.cpp

@ -29,7 +29,6 @@
#include <errno.h> #include <errno.h>
#include "config.hpp" #include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
static static
@ -53,9 +52,8 @@ namespace mergerfs
off_t size, off_t size,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EPERM; return -EPERM;

3
src/getattr.cpp

@ -68,8 +68,9 @@ namespace mergerfs
getattr(const char *fusepath, getattr(const char *fusepath,
struct stat *buf) struct stat *buf)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return (*buf = config.controlfilestat,0); return (*buf = config.controlfilestat,0);

5
src/getxattr.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -112,8 +114,9 @@ namespace mergerfs
char *buf, char *buf,
size_t count) size_t count)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _getxattr_controlfile(config, return _getxattr_controlfile(config,

6
src/ioctl.cpp

@ -32,7 +32,6 @@
#include "config.hpp" #include "config.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
#include "ugid.hpp"
static static
int int
@ -86,9 +85,8 @@ namespace mergerfs
unsigned int flags, unsigned int flags,
void *data) void *data)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EINVAL; return -EINVAL;

5
src/link.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -76,8 +78,9 @@ namespace mergerfs
link(const char *from, link(const char *from,
const char *to) const char *to)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(from == config.controlfile) if(from == config.controlfile)
return -EPERM; return -EPERM;

5
src/listxattr.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -101,8 +103,9 @@ namespace mergerfs
char *list, char *list,
size_t size) size_t size)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _listxattr_controlfile(list, return _listxattr_controlfile(list,

5
src/mkdir.cpp

@ -82,8 +82,9 @@ namespace mergerfs
mkdir(const char *fusepath, mkdir(const char *fusepath,
mode_t mode) mode_t mode)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EEXIST; return -EEXIST;
@ -92,7 +93,7 @@ namespace mergerfs
*config.create, *config.create,
config.srcmounts, config.srcmounts,
fusepath, fusepath,
mode);
(mode & ~fc->umask));
} }
} }
} }

7
src/mknod.cpp

@ -60,7 +60,7 @@ _mknod(const fs::SearchFunc searchFunc,
if(fs::path_exists(srcmounts,fusepath)) if(fs::path_exists(srcmounts,fusepath))
return -EEXIST; return -EEXIST;
dirname = fs::dirname(fusepath);
dirname = fs::dirname(fusepath);
searchFunc(srcmounts,dirname,existingpath); searchFunc(srcmounts,dirname,existingpath);
if(existingpath.empty()) if(existingpath.empty())
return -ENOENT; return -ENOENT;
@ -85,8 +85,9 @@ namespace mergerfs
mode_t mode, mode_t mode,
dev_t rdev) dev_t rdev)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EEXIST; return -EEXIST;
@ -95,7 +96,7 @@ namespace mergerfs
*config.create, *config.create,
config.srcmounts, config.srcmounts,
fusepath, fusepath,
mode,
(mode & ~fc->umask),
rdev); rdev);
} }
} }

3
src/open.cpp

@ -83,8 +83,9 @@ namespace mergerfs
open(const char *fusepath, open(const char *fusepath,
struct fuse_file_info *fileinfo) struct fuse_file_info *fileinfo)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);;
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _open_controlfile(fileinfo->fh); return _open_controlfile(fileinfo->fh);

3
src/read.cpp

@ -77,8 +77,7 @@ namespace mergerfs
off_t offset, off_t offset,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const config::Config &config = config::get();
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _read_controlfile(config.readstr, return _read_controlfile(config.readstr,

3
src/read_buf.cpp

@ -108,8 +108,7 @@ namespace mergerfs
off_t offset, off_t offset,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const config::Config &config = config::get();
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _read_buf_controlfile(config.readstr, return _read_buf_controlfile(config.readstr,

3
src/readdir.cpp

@ -122,8 +122,9 @@ namespace mergerfs
off_t offset, off_t offset,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
return _readdir(config.srcmounts, return _readdir(config.srcmounts,
fusepath, fusepath,

3
src/readlink.cpp

@ -72,8 +72,9 @@ namespace mergerfs
char *buf, char *buf,
size_t size) size_t size)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EINVAL; return -EINVAL;

3
src/release.cpp

@ -71,8 +71,7 @@ namespace mergerfs
release(const char *fusepath, release(const char *fusepath,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const config::Config &config = config::get();
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _release_controlfile(fi->fh); return _release_controlfile(fi->fh);

5
src/removexattr.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -78,8 +80,9 @@ namespace mergerfs
removexattr(const char *fusepath, removexattr(const char *fusepath,
const char *attrname) const char *attrname)
{ {
const ugid::SetResetGuard uid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -ENOTSUP; return -ENOTSUP;

5
src/rename.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -67,8 +69,9 @@ namespace mergerfs
rename(const char *from, rename(const char *from,
const char *to) const char *to)
{ {
const ugid::SetResetGuard uid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(from == config.controlfile) if(from == config.controlfile)
return -ENOENT; return -ENOENT;

5
src/rmdir.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -70,8 +72,9 @@ namespace mergerfs
int int
rmdir(const char *fusepath) rmdir(const char *fusepath)
{ {
const ugid::SetResetGuard uid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -ENOTDIR; return -ENOTDIR;

5
src/setxattr.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <sstream> #include <sstream>
@ -146,8 +148,9 @@ namespace mergerfs
size_t attrvalsize, size_t attrvalsize,
int flags) int flags)
{ {
const ugid::SetResetGuard uid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _setxattr_controlfile(config::get_writable(), return _setxattr_controlfile(config::get_writable(),

3
src/statfs.cpp

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

3
src/symlink.cpp

@ -64,8 +64,9 @@ namespace mergerfs
symlink(const char *oldpath, symlink(const char *oldpath,
const char *newpath) const char *newpath)
{ {
const ugid::SetResetGuard uid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(oldpath == config.controlfile || if(oldpath == config.controlfile ||
newpath == config.controlfile) newpath == config.controlfile)

3
src/truncate.cpp

@ -76,8 +76,9 @@ namespace mergerfs
truncate(const char *fusepath, truncate(const char *fusepath,
off_t size) off_t size)
{ {
const ugid::SetResetGuard uid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EPERM; return -EPERM;

31
src/ugid.cpp

@ -0,0 +1,31 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include "ugid.hpp"
#if defined LINUX
#elif defined OSX
#else
pthread_mutex_t mergerfs::ugid::SetResetGuard::lock = PTHREAD_MUTEX_INITIALIZER;
#endif

72
src/ugid.hpp

@ -25,70 +25,12 @@
#ifndef __UGID_HPP__ #ifndef __UGID_HPP__
#define __UGID_HPP__ #define __UGID_HPP__
#include <fuse.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
{
SetResetGuard()
{
const struct fuse_context *fc = fuse_get_context();
olduid = ::getuid();
oldgid = ::getgid();
oldumask = ::umask(fc->umask);
newuid = fc->uid;
newgid = fc->gid;
newumask = fc->umask;
if(olduid != newuid)
::seteuid(newuid);
if(oldgid != newgid)
::setegid(newgid);
}
SetResetGuard(uid_t u,
gid_t g,
mode_t m)
{
olduid = ::getuid();
oldgid = ::getgid();
oldumask = ::umask(m);
newuid = u;
newgid = g;
newumask = m;
if(olduid != newuid)
::seteuid(newuid);
if(oldgid != newgid)
::setegid(newgid);
}
~SetResetGuard()
{
::umask(oldumask);
if(olduid != newuid)
::seteuid(olduid);
if(oldgid != newgid)
::setegid(oldgid);
}
uid_t olduid;
gid_t oldgid;
mode_t oldumask;
uid_t newuid;
gid_t newgid;
mode_t newumask;
};
}
}
#if defined LINUX
#include "ugid_linux.hpp"
#elif defined OSX
#include "ugid_osx.hpp"
#else
#include "ugid_mutex.hpp"
#endif
#endif /* __UGID_HPP__ */ #endif /* __UGID_HPP__ */

64
src/ugid_linux.hpp

@ -0,0 +1,64 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/syscall.h>
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
{
olduid = ::geteuid();
oldgid = ::getegid();
newuid = _newuid;
newgid = _newgid;
if(newgid != oldgid)
::syscall(SYS_setregid,-1,newgid);
if(newuid != olduid)
::syscall(SYS_setreuid,-1,newuid);
}
~SetResetGuard()
{
if(olduid != newuid)
::syscall(SYS_setreuid,-1,olduid);
if(oldgid != newgid)
::syscall(SYS_setregid,-1,oldgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
};
}
}

68
src/ugid_mutex.hpp

@ -0,0 +1,68 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
{
pthread_mutex_lock(&lock);
olduid = ::geteuid();
oldgid = ::getegid();
newuid = _newuid;
newgid = _newgid;
if(newgid != oldgid)
setegid(newgid);
if(newuid != olduid)
seteuid(newuid);
}
~SetResetGuard()
{
if(olduid != newuid)
seteuid(newuid);
if(oldgid != newgid)
setegid(newgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
static pthread_mutex_t lock;
};
}
}

58
src/ugid_osx.hpp

@ -0,0 +1,58 @@
/*
The MIT License (MIT)
Copyright (c) 2014 Antonio SJ Musumeci <trapexit@spawn.link>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#include <sys/types.h>
#include <sys/unistd.h>
namespace mergerfs
{
namespace ugid
{
struct SetResetGuard
{
SetResetGuard(const uid_t _newuid,
const gid_t _newgid)
{
olduid = ::geteuid();
oldgid = ::getegid();
newuid = _newuid;
newgid = _newgid;
if(newgid != oldgid || newuid != olduid)
pthread_setugid_np(newuid,newgid);
}
~SetResetGuard()
{
if(newgid != oldgid || newuid != olduid)
pthread_setugid_np(newuid,newgid);
}
uid_t olduid;
gid_t oldgid;
uid_t newuid;
gid_t newgid;
};
}
}

5
src/unlink.cpp

@ -22,6 +22,8 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
@ -71,8 +73,9 @@ namespace mergerfs
int int
unlink(const char *fusepath) unlink(const char *fusepath)
{ {
const ugid::SetResetGuard ugid;
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get(); const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EPERM; return -EPERM;

11
src/utimens.cpp

@ -22,8 +22,11 @@
THE SOFTWARE. THE SOFTWARE.
*/ */
#include <fuse.h>
#include <errno.h> #include <errno.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <string> #include <string>
#include <vector> #include <vector>
@ -31,7 +34,6 @@
#include "ugid.hpp" #include "ugid.hpp"
#include "fs.hpp" #include "fs.hpp"
#include "config.hpp" #include "config.hpp"
#include "assert.hpp"
using std::string; using std::string;
using std::vector; using std::vector;
@ -73,8 +75,9 @@ namespace mergerfs
utimens(const char *fusepath, utimens(const char *fusepath,
const struct timespec ts[2]) const struct timespec ts[2])
{ {
ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const struct fuse_context *fc = fuse_get_context();
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return -EPERM; return -EPERM;

3
src/write.cpp

@ -128,8 +128,7 @@ namespace mergerfs
off_t offset, off_t offset,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const config::Config &config = config::get();
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _write_controlfile(config::get_writable(), return _write_controlfile(config::get_writable(),

4
src/write_buf.cpp

@ -28,7 +28,6 @@
#include <fuse.h> #include <fuse.h>
#include "config.hpp" #include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp" #include "fileinfo.hpp"
#include "write.hpp" #include "write.hpp"
@ -93,8 +92,7 @@ namespace mergerfs
off_t offset, off_t offset,
struct fuse_file_info *fi) struct fuse_file_info *fi)
{ {
const ugid::SetResetGuard ugid;
const config::Config &config = config::get();
const config::Config &config = config::get();
if(fusepath == config.controlfile) if(fusepath == config.controlfile)
return _write_buf_controlfile(config.controlfile, return _write_buf_controlfile(config.controlfile,

Loading…
Cancel
Save