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

This commit is contained in:
Antonio SJ Musumeci 2014-07-29 00:00:42 -04:00
parent 45cec2d301
commit 7b0d703f00
35 changed files with 50 additions and 419 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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&

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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);
}
}
}

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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);
}
}

View File

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

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

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

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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,

View File

@ -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,

View File

@ -22,48 +22,13 @@
THE SOFTWARE.
*/
#include <string>
#include <stdlib.h>
#include <fuse.h>
#include "config.hpp"
#include <stdlib.h>
#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);
}

View File

@ -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