From ce8e6e973c1b4fb1261b29ec02dad069bff61c6c Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Fri, 15 Mar 2024 16:47:57 +0100 Subject: [PATCH 1/4] sysfs: forbid write() It's just dangerous to allow passthrough of write() syscall anywhere under emulated sysfs subtree. Let's forbid it. Signed-off-by: Alexander Mikhalitsyn --- src/sysfs_fuse.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/sysfs_fuse.c b/src/sysfs_fuse.c index d26d7c74..bf75ba99 100644 --- a/src/sysfs_fuse.c +++ b/src/sysfs_fuse.c @@ -307,11 +307,7 @@ __lxcfs_fuse_ops int sys_write(const char *path, const char *buf, size_t size, if (f->type != LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_SUBFILE) return -EINVAL; - fd = open(path, O_WRONLY | O_CLOEXEC); - if (fd == -1) - return -errno; - - return pwrite(fd, buf, size, offset); + return -EACCES; } static int sys_readdir_legacy(const char *path, void *buf, fuse_fill_dir_t filler, From 000b539f1b358d4f9536247cccd34da6c48b6e77 Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Fri, 15 Mar 2024 16:49:47 +0100 Subject: [PATCH 2/4] lxcfs: introduce new option --enable-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 --enable-cgroup to explicitly enable old cgroup emulation code 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/lxcfs.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lxcfs.c b/src/lxcfs.c index c55a3888..9fb19cfd 100644 --- a/src/lxcfs.c +++ b/src/lxcfs.c @@ -661,6 +661,8 @@ static int do_sys_releasedir(const char *path, struct fuse_file_info *fi) return __sys_releasedir(path, fi); } +static bool cgroup_is_enabled = false; + #if HAVE_FUSE3 static int lxcfs_getattr(const char *path, struct stat *sb, struct fuse_file_info *fi) #else @@ -681,7 +683,7 @@ static int lxcfs_getattr(const char *path, struct stat *sb) return 0; } - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_getattr(path, sb); down_users(); @@ -712,7 +714,7 @@ static int lxcfs_opendir(const char *path, struct fuse_file_info *fi) if (strcmp(path, "/") == 0) return 0; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_opendir(path, fi); down_users(); @@ -747,13 +749,13 @@ static int lxcfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, dir_filler(filler, buf, "..", 0) != 0 || dir_filler(filler, buf, "proc", 0) != 0 || dir_filler(filler, buf, "sys", 0) != 0 || - dir_filler(filler, buf, "cgroup", 0) != 0) + (cgroup_is_enabled && dir_filler(filler, buf, "cgroup", 0) != 0)) return -ENOMEM; return 0; } - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_readdir(path, buf, filler, offset, fi); down_users(); @@ -784,7 +786,7 @@ static int lxcfs_access(const char *path, int mode) if (strcmp(path, "/") == 0 && (mode & W_OK) == 0) return 0; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_access(path, mode); down_users(); @@ -846,7 +848,7 @@ static int lxcfs_open(const char *path, struct fuse_file_info *fi) { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_open(path, fi); down_users(); @@ -875,7 +877,7 @@ static int lxcfs_read(const char *path, char *buf, size_t size, off_t offset, { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_read(path, buf, size, offset, fi); down_users(); @@ -904,7 +906,7 @@ int lxcfs_write(const char *path, const char *buf, size_t size, off_t offset, { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_write(path, buf, size, offset, fi); down_users(); @@ -983,7 +985,7 @@ int lxcfs_mkdir(const char *path, mode_t mode) { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_mkdir(path, mode); down_users(); @@ -1001,7 +1003,7 @@ int lxcfs_chown(const char *path, uid_t uid, gid_t gid) { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_chown(path, uid, gid); down_users(); @@ -1028,7 +1030,7 @@ int lxcfs_truncate(const char *path, off_t newsize, struct fuse_file_info *fi) int lxcfs_truncate(const char *path, off_t newsize) #endif { - if (strncmp(path, "/cgroup", 7) == 0) + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) return 0; if (strncmp(path, "/sys", 4) == 0) @@ -1041,7 +1043,7 @@ int lxcfs_rmdir(const char *path) { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_rmdir(path); down_users(); @@ -1059,7 +1061,7 @@ int lxcfs_chmod(const char *path, mode_t mode) { int ret; - if (strncmp(path, "/cgroup", 7) == 0) { + if (cgroup_is_enabled && strncmp(path, "/cgroup", 7) == 0) { up_users(); ret = do_cg_chmod(path, mode); down_users(); @@ -1190,6 +1192,7 @@ static void usage(void) 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(" --enable-cgroup Enable cgroup emulation code"); exit(EXIT_FAILURE); } @@ -1238,6 +1241,7 @@ static const struct option long_options[] = { {"enable-cfs", no_argument, 0, 0 }, {"enable-pidfd", no_argument, 0, 0 }, + {"enable-cgroup", no_argument, 0, 0 }, {"pidfile", required_argument, 0, 'p' }, { }, @@ -1318,6 +1322,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, "enable-cgroup") == 0) + cgroup_is_enabled = true; else usage(); break; From 6239e4b8cb2ec585e3c6a276e4a7f8a6f73c306b Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Fri, 15 Mar 2024 17:13:44 +0100 Subject: [PATCH 3/4] tests: use --enable-cgroup for tests Signed-off-by: Alexander Mikhalitsyn --- tests/main.sh.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/main.sh.in b/tests/main.sh.in index 656bb6a0..42540e33 100755 --- a/tests/main.sh.in +++ b/tests/main.sh.in @@ -45,7 +45,7 @@ if [ -x ${lxcfs} ]; then export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}" fi echo "=> Spawning ${lxcfs} ${LXCFSDIR}" - ${lxcfs} -p ${pidfile} ${LXCFSDIR} & + ${lxcfs} --enable-cgroup -p ${pidfile} ${LXCFSDIR} & LXCFSPID=$! else UNSHARE=0 From 351775512350bfb45c6486f39a7aa7cc76f690c7 Mon Sep 17 00:00:00 2001 From: Alexander Mikhalitsyn Date: Mon, 18 Mar 2024 11:41:01 +0100 Subject: [PATCH 4/4] github: workaround CI issue with ASAN https://github.com/actions/runner-images/issues/9491 https://github.com/google/fuzztest/commit/7b4f288ce94dd92a48a638301bb7ec5df0cf8c94 Signed-off-by: Alexander Mikhalitsyn --- .github/workflows/tests.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 57bd574f..d586440c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,6 +20,12 @@ jobs: - ubuntu-22.04 runs-on: ${{ matrix.os }} steps: + # TODO(mihalicyn): Remove once the following is fixed: + # https://github.com/actions/runner-images/issues/9491 + - name: Reduce ASLR entropy as a temporary workaround + run: | + sudo sysctl -w vm.mmap_rnd_bits=28 + - name: Checkout code uses: actions/checkout@v2 @@ -63,6 +69,12 @@ jobs: - ubuntu-22.04 runs-on: ${{ matrix.os }} steps: + # TODO(mihalicyn): Remove once the following is fixed: + # https://github.com/actions/runner-images/issues/9491 + - name: Reduce ASLR entropy as a temporary workaround + run: | + sudo sysctl -w vm.mmap_rnd_bits=28 + - name: Checkout code uses: actions/checkout@v2