diff --git a/src/bindings.h b/src/bindings.h index 617179df..d746140c 100644 --- a/src/bindings.h +++ b/src/bindings.h @@ -116,6 +116,7 @@ struct lxcfs_opts { * and the use of bool instead of explicited __u32 and __u64 we can't. */ __u32 version; + bool allow_write_on_cgroup; }; typedef enum lxcfs_opt_t { diff --git a/src/cgroup_fuse.c b/src/cgroup_fuse.c index 693b67db..49b6a4d6 100644 --- a/src/cgroup_fuse.c +++ b/src/cgroup_fuse.c @@ -1776,6 +1776,7 @@ __lxcfs_fuse_ops int cg_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { struct fuse_context *fc = fuse_get_context(); + const struct lxcfs_opts *opts = fc->private_data; char *localbuf = NULL; struct cgfs_files *k = NULL; struct file_info *f = INTTYPE_TO_PTR(fi->fh); @@ -1792,6 +1793,9 @@ __lxcfs_fuse_ops int cg_write(const char *path, const char *buf, size_t size, return -EIO; } + if (liblxcfs_has_versioned_opts() && opts && opts->version > 1 && !opts->allow_write_on_cgroup) + return -EACCES; + if (offset) return 0; diff --git a/src/lxcfs.c b/src/lxcfs.c index c55a3888..36f9c57b 100644 --- a/src/lxcfs.c +++ b/src/lxcfs.c @@ -1179,17 +1179,18 @@ static void usage(void) lxcfs_info("Usage: lxcfs \n"); lxcfs_info("lxcfs is a FUSE-based proc, sys and cgroup virtualizing filesystem\n"); lxcfs_info("Options :"); - lxcfs_info(" -d, --debug Run lxcfs with debugging enabled"); - lxcfs_info(" -f, --foreground Run lxcfs in the foreground"); - lxcfs_info(" -h, --help Print help"); - lxcfs_info(" -l, --enable-loadavg Enable loadavg virtualization"); - lxcfs_info(" -o Options to pass directly through fuse"); - lxcfs_info(" -p, --pidfile=FILE Path to use for storing lxcfs pid"); - lxcfs_info(" Default pidfile is %s/lxcfs.pid", RUNTIME_PATH); - lxcfs_info(" -u, --disable-swap Disable swap virtualization"); - lxcfs_info(" -v, --version Print lxcfs version"); - lxcfs_info(" --enable-cfs Enable CPU virtualization via CPU shares"); - lxcfs_info(" --enable-pidfd Use pidfd for process tracking"); + lxcfs_info(" -d, --debug Run lxcfs with debugging enabled"); + lxcfs_info(" -f, --foreground Run lxcfs in the foreground"); + lxcfs_info(" -h, --help Print help"); + lxcfs_info(" -l, --enable-loadavg Enable loadavg virtualization"); + lxcfs_info(" -o Options to pass directly through fuse"); + lxcfs_info(" -p, --pidfile=FILE Path to use for storing lxcfs pid"); + lxcfs_info(" Default pidfile is %s/lxcfs.pid", RUNTIME_PATH); + lxcfs_info(" -u, --disable-swap Disable swap virtualization"); + lxcfs_info(" -v, --version Print lxcfs version"); + lxcfs_info(" --enable-cfs Enable CPU virtualization via CPU shares"); + lxcfs_info(" --enable-pidfd Use pidfd for process tracking"); + lxcfs_info(" --allow-write-on-cgroup Allow write() syscall on cgroup lxcfs subtree"); exit(EXIT_FAILURE); } @@ -1229,17 +1230,18 @@ static int set_pidfile(char *pidfile) } static const struct option long_options[] = { - {"debug", no_argument, 0, 'd' }, - {"disable-swap", no_argument, 0, 'u' }, - {"enable-loadavg", no_argument, 0, 'l' }, - {"foreground", no_argument, 0, 'f' }, - {"help", no_argument, 0, 'h' }, - {"version", no_argument, 0, 'v' }, - - {"enable-cfs", no_argument, 0, 0 }, - {"enable-pidfd", no_argument, 0, 0 }, - - {"pidfile", required_argument, 0, 'p' }, + {"debug", no_argument, 0, 'd' }, + {"disable-swap", no_argument, 0, 'u' }, + {"enable-loadavg", no_argument, 0, 'l' }, + {"foreground", no_argument, 0, 'f' }, + {"help", no_argument, 0, 'h' }, + {"version", no_argument, 0, 'v' }, + + {"enable-cfs", no_argument, 0, 0 }, + {"enable-pidfd", no_argument, 0, 0 }, + {"allow-write-on-cgroup", no_argument, 0, 0 }, + + {"pidfile", required_argument, 0, 'p' }, { }, }; @@ -1309,7 +1311,8 @@ int main(int argc, char *argv[]) opts->swap_off = false; opts->use_pidfd = false; opts->use_cfs = false; - opts->version = 1; + opts->version = 2; + opts->allow_write_on_cgroup = false; while ((c = getopt_long(argc, argv, "dulfhvso:p:", long_options, &idx)) != -1) { switch (c) { @@ -1318,6 +1321,8 @@ int main(int argc, char *argv[]) opts->use_pidfd = true; else if (strcmp(long_options[idx].name, "enable-cfs") == 0) opts->use_cfs = true; + else if (strcmp(long_options[idx].name, "allow-write-on-cgroup") == 0) + opts->allow_write_on_cgroup = true; else usage(); break;