From 1cb167567aa419fcbf61e50ecfce49f482ef4fcb Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Fri, 15 Mar 2024 16:49:47 +0100 Subject: [PATCH] lxcfs: introduce new option --allow-write-on-cgroup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During our private discussion, Stéphane proposed to add a new option to explicitly allow write() syscall for cgroupfs. For a compatibility sake, I kept writes allowed if lxcfs daemon version is very old (has no support for versionized struct lxcfs_opts), but for all new versions by default writing is forbidden. It's worth mentioning that cgroup code in LXCFS is not widely used, because it was written before cgroup namespace era and not actual these days. Signed-off-by: Alexander Mikhalitsyn --- src/bindings.h | 1 + src/cgroup_fuse.c | 4 ++++ src/lxcfs.c | 51 ++++++++++++++++++++++++++--------------------- 3 files changed, 33 insertions(+), 23 deletions(-) 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;