From 0e12d796595b0722d4590d32f757824e3dbf8d10 Mon Sep 17 00:00:00 2001 From: Antonio SJ Musumeci Date: Tue, 17 Jun 2014 19:12:09 -0400 Subject: [PATCH] platform specific code to deal with sete{u,g}id. closes #17 --- Makefile | 8 +++++ src/access.cpp | 3 +- src/chmod.cpp | 5 ++-- src/chown.cpp | 3 +- src/create.cpp | 9 +++--- src/fallocate.cpp | 6 ++-- src/fgetattr.cpp | 6 ++-- src/flush.cpp | 3 -- src/fsync.cpp | 6 ++-- src/ftruncate.cpp | 6 ++-- src/getattr.cpp | 3 +- src/getxattr.cpp | 5 +++- src/ioctl.cpp | 6 ++-- src/link.cpp | 5 +++- src/listxattr.cpp | 5 +++- src/mkdir.cpp | 5 ++-- src/mknod.cpp | 7 +++-- src/open.cpp | 3 +- src/read.cpp | 3 +- src/read_buf.cpp | 3 +- src/readdir.cpp | 3 +- src/readlink.cpp | 3 +- src/release.cpp | 3 +- src/removexattr.cpp | 5 +++- src/rename.cpp | 5 +++- src/rmdir.cpp | 5 +++- src/setxattr.cpp | 5 +++- src/statfs.cpp | 3 +- src/symlink.cpp | 3 +- src/truncate.cpp | 3 +- src/ugid.cpp | 31 +++++++++++++++++++ src/ugid.hpp | 72 +++++---------------------------------------- src/ugid_linux.hpp | 64 ++++++++++++++++++++++++++++++++++++++++ src/ugid_mutex.hpp | 68 ++++++++++++++++++++++++++++++++++++++++++ src/ugid_osx.hpp | 58 ++++++++++++++++++++++++++++++++++++ src/unlink.cpp | 5 +++- src/utimens.cpp | 11 ++++--- src/write.cpp | 3 +- src/write_buf.cpp | 4 +-- 39 files changed, 323 insertions(+), 131 deletions(-) create mode 100644 src/ugid.cpp create mode 100644 src/ugid_linux.hpp create mode 100644 src/ugid_mutex.hpp create mode 100644 src/ugid_osx.hpp diff --git a/Makefile b/Makefile index 8196a015..a3ac3396 100644 --- a/Makefile +++ b/Makefile @@ -74,6 +74,14 @@ $(warning "xattr not available: disabling") CFLAGS += -DWITHOUT_XATTR endif +KERNEL = $(shell uname -s) +ifeq ($(KERNEL),Linux) + CFLAGS += -DLINUX +endif +ifeq ($(KERNEL),Darwin) + CFLAGS += -DOSX +endif + all: $(TARGET) help: diff --git a/src/access.cpp b/src/access.cpp index a51cc2f1..aa8b6a98 100644 --- a/src/access.cpp +++ b/src/access.cpp @@ -70,8 +70,9 @@ namespace mergerfs access(const char *fusepath, int mask) { - const ugid::SetResetGuard ugid; + 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) return _access(*config.search, diff --git a/src/chmod.cpp b/src/chmod.cpp index 468c2e25..2e7b8b68 100644 --- a/src/chmod.cpp +++ b/src/chmod.cpp @@ -73,8 +73,9 @@ namespace mergerfs chmod(const char *fusepath, 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) return -EPERM; diff --git a/src/chown.cpp b/src/chown.cpp index 10639727..695955af 100644 --- a/src/chown.cpp +++ b/src/chown.cpp @@ -76,8 +76,9 @@ namespace mergerfs uid_t uid, gid_t gid) { - const ugid::SetResetGuard ugid; + 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) return -EPERM; diff --git a/src/create.cpp b/src/create.cpp index 99bda9e4..64986223 100644 --- a/src/create.cpp +++ b/src/create.cpp @@ -76,7 +76,7 @@ _create(const fs::SearchFunc searchFunc, createPathFunc(srcmounts,dirname,createpath); if(createpath.empty()) return -ENOSPC; - + if(createpath[0].base != existingpath[0].base) fs::clonepath(existingpath[0].base,createpath[0].base,dirname); @@ -100,8 +100,9 @@ namespace mergerfs mode_t mode, 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) return _create_controlfile(fileinfo->fh); @@ -110,7 +111,7 @@ namespace mergerfs *config.create, config.srcmounts, fusepath, - mode, + (mode & ~fc->umask), fileinfo->flags, fileinfo->fh); } diff --git a/src/fallocate.cpp b/src/fallocate.cpp index a99a2049..4e402e9a 100644 --- a/src/fallocate.cpp +++ b/src/fallocate.cpp @@ -31,7 +31,6 @@ #include #include -#include "ugid.hpp" #include "config.hpp" #include "fileinfo.hpp" @@ -77,9 +76,8 @@ namespace mergerfs off_t len, 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) return -EINVAL; diff --git a/src/fgetattr.cpp b/src/fgetattr.cpp index 2e82a46b..7103497e 100644 --- a/src/fgetattr.cpp +++ b/src/fgetattr.cpp @@ -30,7 +30,6 @@ #include #include "config.hpp" -#include "ugid.hpp" #include "fileinfo.hpp" static @@ -54,9 +53,8 @@ namespace mergerfs struct stat *st, 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) return (*st = config.controlfilestat,0); diff --git a/src/flush.cpp b/src/flush.cpp index e2ce054b..6d4fd705 100644 --- a/src/flush.cpp +++ b/src/flush.cpp @@ -27,7 +27,6 @@ #include #include -#include "ugid.hpp" #include "fileinfo.hpp" static @@ -53,8 +52,6 @@ namespace mergerfs flush(const char *path, struct fuse_file_info *fi) { - const ugid::SetResetGuard ugid; - return _flush(((FileInfo*)fi->fh)->fd); } } diff --git a/src/fsync.cpp b/src/fsync.cpp index d63e9a8c..16726624 100644 --- a/src/fsync.cpp +++ b/src/fsync.cpp @@ -35,7 +35,6 @@ #include #include "config.hpp" -#include "ugid.hpp" #include "fileinfo.hpp" static @@ -61,9 +60,8 @@ namespace mergerfs int isdatasync, 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) return 0; diff --git a/src/ftruncate.cpp b/src/ftruncate.cpp index b7172908..d3e3caba 100644 --- a/src/ftruncate.cpp +++ b/src/ftruncate.cpp @@ -29,7 +29,6 @@ #include #include "config.hpp" -#include "ugid.hpp" #include "fileinfo.hpp" static @@ -53,9 +52,8 @@ namespace mergerfs off_t size, 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) return -EPERM; diff --git a/src/getattr.cpp b/src/getattr.cpp index bfed8942..8e771cb0 100644 --- a/src/getattr.cpp +++ b/src/getattr.cpp @@ -68,8 +68,9 @@ namespace mergerfs getattr(const char *fusepath, struct stat *buf) { - const ugid::SetResetGuard ugid; + 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) return (*buf = config.controlfilestat,0); diff --git a/src/getxattr.cpp b/src/getxattr.cpp index 6937427b..4985a703 100644 --- a/src/getxattr.cpp +++ b/src/getxattr.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include @@ -112,8 +114,9 @@ namespace mergerfs char *buf, size_t count) { - const ugid::SetResetGuard ugid; + 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) return _getxattr_controlfile(config, diff --git a/src/ioctl.cpp b/src/ioctl.cpp index 045c78af..ccf0ea2d 100644 --- a/src/ioctl.cpp +++ b/src/ioctl.cpp @@ -32,7 +32,6 @@ #include "config.hpp" #include "fileinfo.hpp" -#include "ugid.hpp" static int @@ -86,9 +85,8 @@ namespace mergerfs unsigned int flags, 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) return -EINVAL; diff --git a/src/link.cpp b/src/link.cpp index 428022e6..607182bc 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include @@ -76,8 +78,9 @@ namespace mergerfs link(const char *from, const char *to) { - const ugid::SetResetGuard ugid; + const struct fuse_context *fc = fuse_get_context(); const config::Config &config = config::get(); + const ugid::SetResetGuard ugid(fc->uid,fc->gid); if(from == config.controlfile) return -EPERM; diff --git a/src/listxattr.cpp b/src/listxattr.cpp index de3af976..e3dd3ac8 100644 --- a/src/listxattr.cpp +++ b/src/listxattr.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include @@ -101,8 +103,9 @@ namespace mergerfs char *list, size_t size) { - const ugid::SetResetGuard ugid; + 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) return _listxattr_controlfile(list, diff --git a/src/mkdir.cpp b/src/mkdir.cpp index f250b236..7643b325 100644 --- a/src/mkdir.cpp +++ b/src/mkdir.cpp @@ -82,8 +82,9 @@ namespace mergerfs mkdir(const char *fusepath, mode_t mode) { - const ugid::SetResetGuard ugid; + 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) return -EEXIST; @@ -92,7 +93,7 @@ namespace mergerfs *config.create, config.srcmounts, fusepath, - mode); + (mode & ~fc->umask)); } } } diff --git a/src/mknod.cpp b/src/mknod.cpp index 9c860f38..25711008 100644 --- a/src/mknod.cpp +++ b/src/mknod.cpp @@ -60,7 +60,7 @@ _mknod(const fs::SearchFunc searchFunc, if(fs::path_exists(srcmounts,fusepath)) return -EEXIST; - dirname = fs::dirname(fusepath); + dirname = fs::dirname(fusepath); searchFunc(srcmounts,dirname,existingpath); if(existingpath.empty()) return -ENOENT; @@ -85,8 +85,9 @@ namespace mergerfs mode_t mode, dev_t rdev) { - const ugid::SetResetGuard ugid; + 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) return -EEXIST; @@ -95,7 +96,7 @@ namespace mergerfs *config.create, config.srcmounts, fusepath, - mode, + (mode & ~fc->umask), rdev); } } diff --git a/src/open.cpp b/src/open.cpp index 9b05a968..508d58b7 100644 --- a/src/open.cpp +++ b/src/open.cpp @@ -83,8 +83,9 @@ namespace mergerfs open(const char *fusepath, struct fuse_file_info *fileinfo) { - const ugid::SetResetGuard ugid; + 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) return _open_controlfile(fileinfo->fh); diff --git a/src/read.cpp b/src/read.cpp index 56f8c204..403c0021 100644 --- a/src/read.cpp +++ b/src/read.cpp @@ -77,8 +77,7 @@ namespace mergerfs off_t offset, 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) return _read_controlfile(config.readstr, diff --git a/src/read_buf.cpp b/src/read_buf.cpp index 28469f87..c349005c 100644 --- a/src/read_buf.cpp +++ b/src/read_buf.cpp @@ -108,8 +108,7 @@ namespace mergerfs off_t offset, 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) return _read_buf_controlfile(config.readstr, diff --git a/src/readdir.cpp b/src/readdir.cpp index cbf5f416..a88ffc1e 100644 --- a/src/readdir.cpp +++ b/src/readdir.cpp @@ -122,8 +122,9 @@ namespace mergerfs off_t offset, struct fuse_file_info *fi) { - const ugid::SetResetGuard ugid; + const struct fuse_context *fc = fuse_get_context(); const config::Config &config = config::get(); + const ugid::SetResetGuard ugid(fc->uid,fc->gid); return _readdir(config.srcmounts, fusepath, diff --git a/src/readlink.cpp b/src/readlink.cpp index 863be8f6..71ccab48 100644 --- a/src/readlink.cpp +++ b/src/readlink.cpp @@ -72,8 +72,9 @@ namespace mergerfs char *buf, size_t size) { - const ugid::SetResetGuard ugid; + 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) return -EINVAL; diff --git a/src/release.cpp b/src/release.cpp index 7d9d8ede..19a15c40 100644 --- a/src/release.cpp +++ b/src/release.cpp @@ -71,8 +71,7 @@ namespace mergerfs release(const char *fusepath, 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) return _release_controlfile(fi->fh); diff --git a/src/removexattr.cpp b/src/removexattr.cpp index 6afe315a..22270285 100644 --- a/src/removexattr.cpp +++ b/src/removexattr.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include @@ -78,8 +80,9 @@ namespace mergerfs removexattr(const char *fusepath, const char *attrname) { - const ugid::SetResetGuard uid; + 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) return -ENOTSUP; diff --git a/src/rename.cpp b/src/rename.cpp index 989110d8..99cfae93 100644 --- a/src/rename.cpp +++ b/src/rename.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include #include @@ -67,8 +69,9 @@ namespace mergerfs rename(const char *from, const char *to) { - const ugid::SetResetGuard uid; + const struct fuse_context *fc = fuse_get_context(); const config::Config &config = config::get(); + const ugid::SetResetGuard ugid(fc->uid,fc->gid); if(from == config.controlfile) return -ENOENT; diff --git a/src/rmdir.cpp b/src/rmdir.cpp index ed519ef5..172ba3b6 100644 --- a/src/rmdir.cpp +++ b/src/rmdir.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include @@ -70,8 +72,9 @@ namespace mergerfs int rmdir(const char *fusepath) { - const ugid::SetResetGuard uid; + 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) return -ENOTDIR; diff --git a/src/setxattr.cpp b/src/setxattr.cpp index 03bc5656..0106b3f9 100644 --- a/src/setxattr.cpp +++ b/src/setxattr.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include #include @@ -146,8 +148,9 @@ namespace mergerfs size_t attrvalsize, int flags) { - const ugid::SetResetGuard uid; + 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) return _setxattr_controlfile(config::get_writable(), diff --git a/src/statfs.cpp b/src/statfs.cpp index 20f5cedb..4432af52 100644 --- a/src/statfs.cpp +++ b/src/statfs.cpp @@ -124,8 +124,9 @@ namespace mergerfs statfs(const char *fusepath, struct statvfs *stat) { - const ugid::SetResetGuard uid; + const struct fuse_context *fc = fuse_get_context(); const config::Config &config = config::get(); + const ugid::SetResetGuard ugid(fc->uid,fc->gid); return _statfs(config.srcmounts, *stat); diff --git a/src/symlink.cpp b/src/symlink.cpp index 14db2474..b55cf6c9 100644 --- a/src/symlink.cpp +++ b/src/symlink.cpp @@ -64,8 +64,9 @@ namespace mergerfs symlink(const char *oldpath, const char *newpath) { - const ugid::SetResetGuard uid; + const struct fuse_context *fc = fuse_get_context(); const config::Config &config = config::get(); + const ugid::SetResetGuard ugid(fc->uid,fc->gid); if(oldpath == config.controlfile || newpath == config.controlfile) diff --git a/src/truncate.cpp b/src/truncate.cpp index b153d20f..31fda2e4 100644 --- a/src/truncate.cpp +++ b/src/truncate.cpp @@ -76,8 +76,9 @@ namespace mergerfs truncate(const char *fusepath, off_t size) { - const ugid::SetResetGuard uid; + 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) return -EPERM; diff --git a/src/ugid.cpp b/src/ugid.cpp new file mode 100644 index 00000000..3d8b47f8 --- /dev/null +++ b/src/ugid.cpp @@ -0,0 +1,31 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + 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 diff --git a/src/ugid.hpp b/src/ugid.hpp index a72cfc0d..78b861f6 100644 --- a/src/ugid.hpp +++ b/src/ugid.hpp @@ -25,70 +25,12 @@ #ifndef __UGID_HPP__ #define __UGID_HPP__ -#include - -#include -#include -#include - -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__ */ diff --git a/src/ugid_linux.hpp b/src/ugid_linux.hpp new file mode 100644 index 00000000..180fe91b --- /dev/null +++ b/src/ugid_linux.hpp @@ -0,0 +1,64 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + 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 +#include +#include +#include + +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; + }; + } +} diff --git a/src/ugid_mutex.hpp b/src/ugid_mutex.hpp new file mode 100644 index 00000000..b6b4f022 --- /dev/null +++ b/src/ugid_mutex.hpp @@ -0,0 +1,68 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + 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 +#include +#include +#include + +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; + }; + } +} diff --git a/src/ugid_osx.hpp b/src/ugid_osx.hpp new file mode 100644 index 00000000..89d3e9ce --- /dev/null +++ b/src/ugid_osx.hpp @@ -0,0 +1,58 @@ +/* + The MIT License (MIT) + + Copyright (c) 2014 Antonio SJ Musumeci + + 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 +#include + +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; + }; + } +} diff --git a/src/unlink.cpp b/src/unlink.cpp index 4003a448..f41ff9ff 100644 --- a/src/unlink.cpp +++ b/src/unlink.cpp @@ -22,6 +22,8 @@ THE SOFTWARE. */ +#include + #include #include @@ -71,8 +73,9 @@ namespace mergerfs int unlink(const char *fusepath) { - const ugid::SetResetGuard ugid; + 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) return -EPERM; diff --git a/src/utimens.cpp b/src/utimens.cpp index 2cfdcdf5..581c4ef5 100644 --- a/src/utimens.cpp +++ b/src/utimens.cpp @@ -22,8 +22,11 @@ THE SOFTWARE. */ +#include + #include -#include +#include +#include #include #include @@ -31,7 +34,6 @@ #include "ugid.hpp" #include "fs.hpp" #include "config.hpp" -#include "assert.hpp" using std::string; using std::vector; @@ -73,8 +75,9 @@ namespace mergerfs utimens(const char *fusepath, 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) return -EPERM; diff --git a/src/write.cpp b/src/write.cpp index 15432a07..110d368f 100644 --- a/src/write.cpp +++ b/src/write.cpp @@ -128,8 +128,7 @@ namespace mergerfs off_t offset, 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) return _write_controlfile(config::get_writable(), diff --git a/src/write_buf.cpp b/src/write_buf.cpp index 6838d79d..19233cd0 100644 --- a/src/write_buf.cpp +++ b/src/write_buf.cpp @@ -28,7 +28,6 @@ #include #include "config.hpp" -#include "ugid.hpp" #include "fileinfo.hpp" #include "write.hpp" @@ -93,8 +92,7 @@ namespace mergerfs off_t offset, 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) return _write_buf_controlfile(config.controlfile,