Browse Source

only allow manipulation of runtime settings via xattrs. closes #22

pull/30/head
Antonio SJ Musumeci 10 years ago
parent
commit
7b0d703f00
  1. 6
      src/access.cpp
  2. 3
      src/chmod.cpp
  3. 3
      src/chown.cpp
  4. 28
      src/config.cpp
  5. 4
      src/config.hpp
  6. 14
      src/create.cpp
  7. 11
      src/fallocate.cpp
  8. 21
      src/fgetattr.cpp
  9. 10
      src/flush.cpp
  10. 9
      src/fsync.cpp
  11. 9
      src/ftruncate.cpp
  12. 26
      src/getattr.cpp
  13. 5
      src/getxattr.cpp
  14. 9
      src/ioctl.cpp
  15. 3
      src/link.cpp
  16. 4
      src/listxattr.cpp
  17. 4
      src/mkdir.cpp
  18. 4
      src/mknod.cpp
  19. 13
      src/open.cpp
  20. 30
      src/read.cpp
  21. 54
      src/read_buf.cpp
  22. 3
      src/readlink.cpp
  23. 22
      src/release.cpp
  24. 1
      src/removexattr.cpp
  25. 4
      src/rename.cpp
  26. 4
      src/rmdir.cpp
  27. 4
      src/setxattr.cpp
  28. 1
      src/statfs.cpp
  29. 4
      src/symlink.cpp
  30. 5
      src/truncate.cpp
  31. 5
      src/unlink.cpp
  32. 4
      src/utimens.cpp
  33. 80
      src/write.cpp
  34. 48
      src/write_buf.cpp
  35. 12
      src/xattr.hpp

6
src/access.cpp

@ -74,12 +74,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return _access(*config.search,
config.srcmounts,
"/",
mask);
return _access(*config.search,
config.srcmounts,
fusepath,

3
src/chmod.cpp

@ -77,9 +77,6 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return -EPERM;
return _chmod(*config.action,
config.srcmounts,
fusepath,

3
src/chown.cpp

@ -80,9 +80,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EPERM;
return _chown(*config.action,
config.srcmounts,
fusepath,

28
src/config.cpp

@ -44,34 +44,6 @@ namespace mergerfs
action = &Policy::ff;
create = &Policy::epmfs;
search = &Policy::ff;
time_t now = time(NULL);
controlfilestat.st_dev = 0;
controlfilestat.st_ino = 0;
controlfilestat.st_mode = (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
controlfilestat.st_nlink = 1;
controlfilestat.st_uid = ::getuid();
controlfilestat.st_gid = ::getgid();
controlfilestat.st_rdev = 0;
controlfilestat.st_size = 0;
controlfilestat.st_blksize = 1024;
controlfilestat.st_blocks = 0;
controlfilestat.st_atime = now;
controlfilestat.st_mtime = now;
controlfilestat.st_ctime = now;
}
std::string
Config::controlfiledata() const
{
std::stringstream ss;
ss << "action=" << (std::string)*action << std::endl
<< "create=" << (std::string)*create << std::endl
<< "search=" << (std::string)*search << std::endl;
return ss.str();
}
const Config&

4
src/config.hpp

@ -42,9 +42,6 @@ namespace mergerfs
public:
Config();
public:
std::string controlfiledata() const;
public:
std::string destmount;
std::vector<std::string> srcmounts;
@ -56,7 +53,6 @@ namespace mergerfs
public:
const std::string controlfile;
struct stat controlfilestat;
};
const Config &get(void);

14
src/create.cpp

@ -43,15 +43,6 @@ using std::vector;
using mergerfs::FileInfo;
using mergerfs::Policy;
static
int
_create_controlfile(uint64_t &fh)
{
fh = (uint64_t)new string;
return 0;
}
static
int
_create(const fs::SearchFunc searchFunc,
@ -68,7 +59,7 @@ _create(const fs::SearchFunc searchFunc,
fs::PathVector createpath;
fs::PathVector existingpath;
dirname = fs::dirname(fusepath);
dirname = fs::dirname(fusepath);
searchFunc(srcmounts,dirname,existingpath);
if(existingpath.empty())
return -ENOENT;
@ -104,9 +95,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return _create_controlfile(fileinfo->fh);
return _create(*config.search,
*config.create,
config.srcmounts,

11
src/fallocate.cpp

@ -31,11 +31,8 @@
#include <errno.h>
#include <fcntl.h>
#include "config.hpp"
#include "fileinfo.hpp"
using namespace mergerfs;
static
int
_fallocate(const int fd,
@ -74,13 +71,9 @@ namespace mergerfs
int mode,
off_t offset,
off_t len,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile)
return -EINVAL;
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
return _fallocate(fileinfo->fd,
mode,

21
src/fgetattr.cpp

@ -29,21 +29,8 @@
#include <unistd.h>
#include <errno.h>
#include "config.hpp"
#include "fileinfo.hpp"
static
int
_fgetattr_controlfile(const struct stat &controlfilestat,
const std::string cfdata,
struct stat &st)
{
st = controlfilestat;
st.st_size = cfdata.size();
return 0;
}
static
int
_fgetattr(const int fd,
@ -65,13 +52,7 @@ namespace mergerfs
struct stat *st,
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
if(fusepath == config.controlfile)
return _fgetattr_controlfile(config.controlfilestat,
config.controlfiledata(),
*st);
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
return _fgetattr(fileinfo->fd,
*st);

10
src/flush.cpp

@ -27,7 +27,6 @@
#include <unistd.h>
#include <errno.h>
#include "config.hpp"
#include "fileinfo.hpp"
static
@ -51,14 +50,9 @@ namespace mergerfs
{
int
flush(const char *fusepath,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return 0;
return _flush(((FileInfo*)fi->fh)->fd);
return _flush(((FileInfo*)ffi->fh)->fd);
}
}
}

9
src/fsync.cpp

@ -34,7 +34,6 @@
#include <unistd.h>
#include <errno.h>
#include "config.hpp"
#include "fileinfo.hpp"
static
@ -58,13 +57,9 @@ namespace mergerfs
int
fsync(const char *fusepath,
int isdatasync,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile)
return 0;
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
return _fsync(fileinfo->fd,
isdatasync);

9
src/ftruncate.cpp

@ -28,7 +28,6 @@
#include <sys/types.h>
#include <errno.h>
#include "config.hpp"
#include "fileinfo.hpp"
static
@ -50,13 +49,9 @@ namespace mergerfs
int
ftruncate(const char *fusepath,
off_t size,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile)
return -EPERM;
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
return _ftruncate(fileinfo->fd,
size);

26
src/getattr.cpp

@ -39,16 +39,26 @@
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
_getattr_controlfile(const struct stat &controlfilestat,
const std::string cfdata,
struct stat &st)
_getattr_controlfile(struct stat &buf)
{
st = controlfilestat;
st.st_size = cfdata.size();
time_t now = time(NULL);
buf.st_dev = 0;
buf.st_ino = 0;
buf.st_mode = (S_IFREG|S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
buf.st_nlink = 1;
buf.st_uid = ::geteuid();
buf.st_gid = ::getegid();
buf.st_rdev = 0;
buf.st_size = 0;
buf.st_blksize = 1024;
buf.st_blocks = 0;
buf.st_atime = now;
buf.st_mtime = now;
buf.st_ctime = now;
return 0;
}
@ -85,9 +95,7 @@ namespace mergerfs
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return _getattr_controlfile(config.controlfilestat,
config.controlfiledata(),
*st);
return _getattr_controlfile(*st);
return _getattr(*config.search,
config.srcmounts,

5
src/getxattr.cpp

@ -39,7 +39,6 @@
using std::string;
using std::vector;
using mergerfs::Policy;
using namespace mergerfs::config;
static
@ -49,7 +48,6 @@ _getxattr_controlfile(const Config &config,
char *buf,
const size_t count)
{
#ifndef WITHOUT_XATTR
size_t len;
string attrvalue;
@ -74,9 +72,6 @@ _getxattr_controlfile(const Config &config,
memcpy(buf,attrvalue.c_str(),len);
return (int)len;
#else
return -ENOTSUP;
#endif
}
static

9
src/ioctl.cpp

@ -30,7 +30,6 @@
#include <sys/ioctl.h>
#include <linux/fs.h>
#include "config.hpp"
#include "fileinfo.hpp"
static
@ -81,15 +80,11 @@ namespace mergerfs
ioctl(const char *fusepath,
int cmd,
void *arg,
struct fuse_file_info *fi,
struct fuse_file_info *ffi,
unsigned int flags,
void *data)
{
const config::Config &config = config::get();
const FileInfo *fileinfo = (FileInfo*)fi->fh;
if(fusepath == config.controlfile)
return -EINVAL;
const FileInfo *fileinfo = (FileInfo*)ffi->fh;
return _ioctl(fileinfo->fd,
cmd,

3
src/link.cpp

@ -98,9 +98,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(from == config.controlfile)
return -EPERM;
return _link(*config.action,
config.srcmounts,
from,

4
src/listxattr.cpp

@ -47,7 +47,6 @@ int
_listxattr_controlfile(char *list,
const size_t size)
{
#ifndef WITHOUT_XATTR
size_t xattrssize;
string xattrs;
@ -65,9 +64,6 @@ _listxattr_controlfile(char *list,
memcpy(list,xattrs.data(),xattrssize);
return xattrssize;
#else
return -ENOTSUP;
#endif
}
static

4
src/mkdir.cpp

@ -39,7 +39,6 @@
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
@ -86,9 +85,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EEXIST;
return _mkdir(*config.search,
*config.create,
config.srcmounts,

4
src/mknod.cpp

@ -40,7 +40,6 @@
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
@ -89,9 +88,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EEXIST;
return _mknod(*config.search,
*config.create,
config.srcmounts,

13
src/open.cpp

@ -40,16 +40,6 @@
using std::string;
using std::vector;
using mergerfs::FileInfo;
using mergerfs::Policy;
static
int
_open_controlfile(uint64_t &fh)
{
fh = (uint64_t)new string;
return 0;
}
static
int
@ -87,9 +77,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);;
if(fusepath == config.controlfile)
return _open_controlfile(fileinfo->fh);
return _open(*config.search,
config.srcmounts,
fusepath,

30
src/read.cpp

@ -31,27 +31,8 @@
#include <string>
#include <algorithm>
#include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp"
using std::string;
static
int
_read_controlfile(const string readstr,
char *buf,
const size_t count)
{
size_t n;
n = std::min(count,readstr.length());
memcpy(buf,readstr.data(),n);
return (int)n;
}
static
int
_read(const int fd,
@ -75,16 +56,9 @@ namespace mergerfs
char *buf,
size_t count,
off_t offset,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return _read_controlfile(config.controlfiledata(),
buf,
count);
return _read(((FileInfo*)fi->fh)->fd,
return _read(((FileInfo*)ffi->fh)->fd,
buf,
count,
offset);

54
src/read_buf.cpp

@ -28,51 +28,8 @@
#include <errno.h>
#include <string.h>
#include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp"
using std::string;
static
void *
memdup(const void *src,
const size_t len)
{
void *dst;
dst = malloc(len);
if(dst == NULL)
return NULL;
memcpy(dst, src, len);
return dst;
}
static
int
_read_buf_controlfile(const string readstr,
struct fuse_bufvec **bufp,
const size_t size)
{
struct fuse_bufvec *src;
src = (fuse_bufvec*)malloc(sizeof(struct fuse_bufvec));
if(src == NULL)
return -ENOMEM;
*src = FUSE_BUFVEC_INIT(std::min(size,readstr.size()));
src->buf->mem = memdup(readstr.data(),readstr.size());
if(src->buf->mem == NULL)
return -ENOMEM;
*bufp = src;
return 0;
}
static
int
_read_buf(const int fd,
@ -106,16 +63,9 @@ namespace mergerfs
struct fuse_bufvec **bufp,
size_t size,
off_t offset,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return _read_buf_controlfile(config.controlfiledata(),
bufp,
size);
return _read_buf(((FileInfo*)fi->fh)->fd,
return _read_buf(((FileInfo*)ffi->fh)->fd,
bufp,
size,
offset);

3
src/readlink.cpp

@ -76,9 +76,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EINVAL;
return _readlink(*config.search,
config.srcmounts,
fusepath,

22
src/release.cpp

@ -24,30 +24,15 @@
#include <fuse.h>
#include <unistd.h>
#include <errno.h>
#include <string>
#include "config.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp"
using std::string;
using mergerfs::FileInfo;
static
int
_release_controlfile(uint64_t &fh)
{
string *strbuf = (string*)fh;
delete strbuf;
fh = 0;
return 0;
}
static
int
_release(uint64_t &fh)
@ -71,11 +56,6 @@ namespace mergerfs
release(const char *fusepath,
struct fuse_file_info *fi)
{
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return _release_controlfile(fi->fh);
return _release(fi->fh);
}
}

1
src/removexattr.cpp

@ -38,7 +38,6 @@
using std::string;
using std::vector;
using mergerfs::Policy;
static
int

4
src/rename.cpp

@ -37,7 +37,6 @@
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
@ -75,9 +74,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(from == config.controlfile)
return -ENOENT;
return _rename(*config.search,
config.srcmounts,
from,

4
src/rmdir.cpp

@ -32,7 +32,6 @@
#include "ugid.hpp"
#include "fs.hpp"
#include "config.hpp"
#include "assert.hpp"
using std::string;
using std::vector;
@ -76,9 +75,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -ENOTDIR;
return _rmdir(*config.action,
config.srcmounts,
fusepath);

4
src/setxattr.cpp

@ -66,7 +66,6 @@ _setxattr_controlfile(config::Config &config,
const size_t attrvalsize,
const int flags)
{
#ifndef WITHOUT_XATTR
const Category *cat;
const Policy *policy;
vector<string> nameparts;
@ -96,9 +95,6 @@ _setxattr_controlfile(config::Config &config,
config.policies[*cat] = policy;
return 0;
#else
return -ENOTSUP;
#endif
}
static

1
src/statfs.cpp

@ -39,7 +39,6 @@ using std::string;
using std::vector;
using std::map;
using std::pair;
using mergerfs::Policy;
static
void

4
src/symlink.cpp

@ -68,10 +68,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(oldpath == config.controlfile ||
newpath == config.controlfile)
return -EPERM;
return _symlink(config.srcmounts,
oldpath,
newpath);

5
src/truncate.cpp

@ -34,11 +34,9 @@
#include "ugid.hpp"
#include "fs.hpp"
#include "config.hpp"
#include "assert.hpp"
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
@ -80,9 +78,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EPERM;
return _truncate(*config.action,
config.srcmounts,
fusepath,

5
src/unlink.cpp

@ -33,11 +33,9 @@
#include "ugid.hpp"
#include "fs.hpp"
#include "config.hpp"
#include "assert.hpp"
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
@ -77,9 +75,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EPERM;
return _unlink(*config.action,
config.srcmounts,
fusepath);

4
src/utimens.cpp

@ -37,7 +37,6 @@
using std::string;
using std::vector;
using mergerfs::Policy;
static
int
@ -79,9 +78,6 @@ namespace mergerfs
const config::Config &config = config::get();
const ugid::SetResetGuard ugid(fc->uid,fc->gid);
if(fusepath == config.controlfile)
return -EPERM;
return _utimens(*config.action,
config.srcmounts,
fusepath,

80
src/write.cpp

@ -27,80 +27,8 @@
#include <errno.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <sstream>
#include "config.hpp"
#include "policy.hpp"
#include "category.hpp"
#include "ugid.hpp"
#include "fileinfo.hpp"
using mergerfs::config::Config;
using mergerfs::Policy;
using mergerfs::Category;
using std::string;
using std::vector;
using std::stringstream;
static
int
_process_kv(Config &config,
const string key,
const string value)
{
const Category *cat;
const Policy *policy;
cat = Category::find(key);
if(cat == Category::invalid)
return -EINVAL;
policy = Policy::find(value);
if(policy == Policy::invalid)
return -EINVAL;
config.policies[*cat] = policy;
return 0;
}
static
int
_write_controlfile(Config &config,
string &existing,
const string buf,
const off_t _offset)
{
size_t bufsize = buf.size();
size_t existingsize = existing.size();
if((existingsize + buf.size()) > 1024)
return (existing.clear(),-EINVAL);
existing += buf;
size_t nlpos = existing.find_first_of('\n',existingsize);
if(nlpos == string::npos)
return 0;
string line = existing.substr(0,nlpos);
existing = existing.substr(nlpos+1);
size_t equalsoffset = line.find_first_of('=');
if(equalsoffset == string::npos)
return -EINVAL;
int rv;
string key = line.substr(0,equalsoffset);
string value = line.substr(equalsoffset+1);
rv = _process_kv(config,key,value);
return ((rv < 0) ? rv : bufsize);
}
static
int
_write(const int fd,
@ -126,14 +54,6 @@ namespace mergerfs
off_t offset,
struct fuse_file_info *fi)
{
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return _write_controlfile(config::get_writable(),
*(string*)fi->fh,
string(buf,count),
offset);
return _write(((FileInfo*)fi->fh)->fd,
buf,
count,

48
src/write_buf.cpp

@ -22,48 +22,13 @@
THE SOFTWARE.
*/
#include <string>
#include <fuse.h>
#include <stdlib.h>
#include <fuse.h>
#include "config.hpp"
#include "fileinfo.hpp"
#include "write.hpp"
using std::string;
static
int
_write_buf_controlfile(const string controlfile,
struct fuse_bufvec &src,
struct fuse_file_info &fi)
{
int rv;
size_t size;
struct fuse_bufvec dst;
size = fuse_buf_size(&src);
dst = FUSE_BUFVEC_INIT(size);
dst.buf->mem = malloc(size);
rv = fuse_buf_copy(&dst,&src,(fuse_buf_copy_flags)0);
if(rv < 0)
{
free(dst.buf->mem);
return rv;
}
rv = mergerfs::write::write(controlfile.c_str(),
(const char*)dst.buf->mem,
size,
0,
&fi);
free(dst.buf->mem);
return rv;
}
static
int
_write_buf(const int fd,
@ -90,16 +55,9 @@ namespace mergerfs
write_buf(const char *fusepath,
struct fuse_bufvec *src,
off_t offset,
struct fuse_file_info *fi)
struct fuse_file_info *ffi)
{
const config::Config &config = config::get();
if(fusepath == config.controlfile)
return _write_buf_controlfile(config.controlfile,
*src,
*fi);
return _write_buf(((FileInfo*)fi->fh)->fd,
return _write_buf(((FileInfo*)ffi->fh)->fd,
*src,
offset);
}

12
src/xattr.hpp

@ -25,3 +25,15 @@
#ifndef WITHOUT_XATTR
#include <attr/xattr.h>
#endif
#ifndef ENOATTR
#define ENOATTR ENODATA
#endif
#ifndef XATTR_CREATE
#define XATTR_CREATE 0x1
#endif
#ifndef XATTR_REPLACE
#define XATTR_REPLACE 0x2
#endif
Loading…
Cancel
Save