Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package lxcfs for openSUSE:Factory checked 
in at 2024-07-16 22:03:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lxcfs (Old)
 and      /work/SRC/openSUSE:Factory/.lxcfs.new.17339 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lxcfs"

Tue Jul 16 22:03:03 2024 rev:23 rq:1187672 version:6.0.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/lxcfs/lxcfs.changes      2024-05-01 
14:58:14.177792125 +0200
+++ /work/SRC/openSUSE:Factory/.lxcfs.new.17339/lxcfs.changes   2024-07-16 
22:03:10.939529509 +0200
@@ -1,0 +2,21 @@
+Sat Jul 13 10:58:47 UTC 2024 - Johannes Kastl 
<[email protected]>
+
+- update to 6.0.1 LTS:
+  * Some of the highlights for this release are:
+    - Support for running multiple instances of LXCFS
+      (--runtime-dir)
+    - Detect systems that has a Yama policy preventing reading
+      process personalities
+  * Detailed changelog
+    - github: add lxcfs live upgrade compatibility test
+    - proc: checks system security policy before trying to get
+      personalities
+    - lxcfs/bindings: Refactor RUNTIME_PATH so that it can be
+      overridden on startup
+    - lxcfs/bindings: add a flag for overriding the runtime dir
+    - github: update coverity test to use Ubuntu 22.04
+    - README.md: add info about how to collect a core dump
+    - github: add ISSUE_TEMPLATE.md
+    - tests: Update for multiple runtime paths
+
+-------------------------------------------------------------------

Old:
----
  lxcfs-6.0.0.tar.gz
  lxcfs-6.0.0.tar.gz.asc

New:
----
  lxcfs-6.0.1.tar.gz
  lxcfs-6.0.1.tar.gz.asc

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ lxcfs.spec ++++++
--- /var/tmp/diff_new_pack.n4xlnd/_old  2024-07-16 22:03:11.527550955 +0200
+++ /var/tmp/diff_new_pack.n4xlnd/_new  2024-07-16 22:03:11.527550955 +0200
@@ -22,7 +22,7 @@
 %endif
 
 Name:           lxcfs
-Version:        6.0.0
+Version:        6.0.1
 Release:        0
 Summary:        FUSE filesystem for LXC
 License:        Apache-2.0

++++++ lxcfs-6.0.0.tar.gz -> lxcfs-6.0.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/.github/ISSUE_TEMPLATE.md 
new/lxcfs-6.0.1/.github/ISSUE_TEMPLATE.md
--- old/lxcfs-6.0.0/.github/ISSUE_TEMPLATE.md   1970-01-01 01:00:00.000000000 
+0100
+++ new/lxcfs-6.0.1/.github/ISSUE_TEMPLATE.md   2024-06-26 04:31:57.000000000 
+0200
@@ -0,0 +1,32 @@
+The template below is mostly useful for bug reports and support questions.
+Feel free to remove anything which doesn't apply to you and add more 
information where it makes sense.
+
+# Required information
+
+ * Distribution:
+   * `cat /etc/os-release` or `cat /etc/lsb-release`
+ * LXCFS version:
+ * The output of
+   * `uname -a`
+   * `cat /proc/1/mounts`
+   * `ps aux | grep lxcfs`
+   * LXCFS logs
+
+# Issue description
+
+A brief description of what failed or what could be improved.
+
+If you have LXCFS crashing, please, collect a crash dump.
+
+# Steps to reproduce
+
+ 1. Step one
+ 2. Step two
+ 3. Step three
+
+# Information to attach
+
+ - [ ] any relevant kernel output (`dmesg`)
+ - [ ] LXCFS daemon output / logs
+ - [ ] LXCFS configuration (Which options were used to start a LXCFS daemon? 
`ps aux | grep lxcfs`)
+ - [ ] in case of crash, a core dump (please, read [how to collect a core 
dump](https://github.com/lxc/lxcfs?tab=readme-ov-file#core-dump))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/.github/workflows/builds.yml 
new/lxcfs-6.0.1/.github/workflows/builds.yml
--- old/lxcfs-6.0.0/.github/workflows/builds.yml        2024-03-28 
03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/.github/workflows/builds.yml        2024-06-26 
04:31:57.000000000 +0200
@@ -10,7 +10,7 @@
 jobs:
   coverity:
     name: Coverity
-    runs-on: ubuntu-20.04
+    runs-on: ubuntu-22.04
     steps:
       - name: Checkout code
         uses: actions/checkout@v2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/.github/workflows/tests.yml 
new/lxcfs-6.0.1/.github/workflows/tests.yml
--- old/lxcfs-6.0.0/.github/workflows/tests.yml 2024-03-28 03:44:27.000000000 
+0100
+++ new/lxcfs-6.0.1/.github/workflows/tests.yml 2024-06-26 04:31:57.000000000 
+0200
@@ -93,3 +93,66 @@
         run: |
           echo 1 | sudo tee /sys/fs/cgroup/cpuset/cgroup.clone_children || true
           sudo -E PATH="${PATH}" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" 
build/tests/main.sh
+
+  live-upgrade-compatibility:
+    name: Live upgrade test
+    strategy:
+      fail-fast: false
+      matrix:
+        compiler:
+          - gcc
+          - clang
+        os:
+          - ubuntu-22.04
+    runs-on: ${{ matrix.os }}
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v2
+
+      - name: Install dependencies
+        run: |
+          sudo add-apt-repository universe
+          sudo apt-get update -qq
+          sudo apt-get install -qq gcc clang
+          sudo apt-get install -qq libfuse3-dev uuid-runtime
+          sudo apt-get install -qq python3 python3-setuptools
+          sudo pip3 install meson==0.55.1 ninja
+
+      - name: Compiler version
+        env:
+          CC: ${{ matrix.compiler }}
+        run: |
+          ${CC} --version
+
+      - name: Build PR head version
+        env:
+          CC: ${{ matrix.compiler }}
+        run: |
+          meson setup -Ddocs=false -Dtests=true -Dinit-script=systemd 
-Dprefix=/usr -Db_sanitize=address,undefined build/
+          meson compile -C build
+
+      - name: Build upstream head version
+        env:
+          CC: ${{ matrix.compiler }}
+        run: |
+          git clone -b stable-6.0 https://github.com/lxc/lxcfs.git 
../upstream-lxcfs
+          cd ../upstream-lxcfs
+          meson setup -Ddocs=false -Dtests=true -Dinit-script=systemd 
-Dprefix=/usr -Db_sanitize=address,undefined build/
+          meson compile -C build
+
+      - name: Test
+        env:
+          CC: ${{ matrix.compiler }}
+          WORKSPACE_PATH: ${{ github.workspace }}
+        run: |
+          UPSTREAM_LXCFS_TREE=$(realpath ${WORKSPACE_PATH}/../upstream-lxcfs)
+          NEW_LXCFS_TREE="${WORKSPACE_PATH}"
+
+          echo "${NEW_LXCFS_TREE}"
+          echo "${UPSTREAM_LXCFS_TREE}"
+
+          cd $UPSTREAM_LXCFS_TREE
+          [ -f build/tests/live-upgrade-test.sh ] || exit 0
+
+          echo 1 | sudo tee /sys/fs/cgroup/cpuset/cgroup.clone_children || true
+          sudo -E PATH="${PATH}" LD_LIBRARY_PATH="${LD_LIBRARY_PATH}" 
build/tests/live-upgrade-test.sh "${NEW_LXCFS_TREE}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/README.md new/lxcfs-6.0.1/README.md
--- old/lxcfs-6.0.0/README.md   2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/README.md   2024-06-26 04:31:57.000000000 +0200
@@ -98,7 +98,7 @@
 lxc.include = /usr/share/lxc/config/common.conf.d/00-lxcfs.conf
 ```
 
-## Using with Docker
+### Using with Docker
 
 ```
 docker run -it -m 256m --memory-swap 256m \
@@ -163,3 +163,29 @@
    usage (100% full) is reported. This provides adequate reporting of
    the memory consumption while preventing applications from assuming more
    SWAP is available.
+
+## Issue reporting
+
+### Core dump
+
+In case of LXCFS crash, it can be extremely useful for us to have a core dump 
of the LXCFS process memory.
+
+1. Please, check `/var/crash` and `coredumpctl list` just in case if you 
already have an LXCFS core dump file
+2. If not, you can use the following way to collect it from your system:
+
+On the machine where you run LXCFS, execute as root:
+```
+# save an old core_pattern setting value:
+cat /proc/sys/kernel/core_pattern > /root/core_pattern.old_value.bak
+
+# set a new one to collect all core dumps:
+echo '|/bin/sh -c $@ -- eval exec gzip --fast > /var/crash/core-%e.%p.gz' > 
/proc/sys/kernel/core_pattern
+
+# wait for the next LXCFS crash and check
+ls -lah /var/crash
+
+# there should be a file with a name like "core-lxcfs.80581.gz". Please, 
upload it somewhere and share with us.
+
+# restore the old "core_pattern" value:
+cat /root/core_pattern.old_value.bak > /proc/sys/kernel/core_pattern
+```
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/meson.build new/lxcfs-6.0.1/meson.build
--- old/lxcfs-6.0.0/meson.build 2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/meson.build 2024-06-26 04:31:57.000000000 +0200
@@ -4,7 +4,7 @@
 project(
     'lxcfs',
     'c',
-    version: '6.0.0',
+    version: '6.0.1',
     license: 'LGPLv2+',
     default_options: [
         'b_colorout=always',
@@ -57,7 +57,7 @@
 conf.set_quoted('BINDIR', bindir)
 conf.set_quoted('LIBDIR', libdir)
 conf.set_quoted('LOCALSTATEDIR', localstatedir)
-conf.set_quoted('RUNTIME_PATH', runtimepath)
+conf.set_quoted('DEFAULT_RUNTIME_PATH', runtimepath)
 conf.set_quoted('SYSCONFDIR', sysconfdir)
 
 conf.set_quoted('LXCCONFDIR', lxcconfdir)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/src/bindings.c 
new/lxcfs-6.0.1/src/bindings.c
--- old/lxcfs-6.0.0/src/bindings.c      2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/src/bindings.c      2024-06-26 04:31:57.000000000 +0200
@@ -7,6 +7,7 @@
 #include <fcntl.h>
 #include <inttypes.h>
 #include <libgen.h>
+#include <linux/limits.h>
 #include <linux/magic.h>
 #include <linux/sched.h>
 #include <pthread.h>
@@ -40,15 +41,32 @@
 #include "syscall_numbers.h"
 #include "utils.h"
 
+/* directory under which we mount the controllers - /run/lxcfs/controllers */
+#define BASEDIR "/lxcfs/controllers"
+#define ROOTDIR "/lxcfs/root"
+
 static bool can_use_pidfd;
 static bool can_use_swap;
 static bool can_use_sys_cpu;
 static bool has_versioned_opts;
 static bool memory_is_cgroupv2;
 static __u32 host_personality;
+static char runtime_path[PATH_MAX] = DEFAULT_RUNTIME_PATH;
+
 
 static volatile sig_atomic_t reload_successful;
 
+
+static char *get_base_dir(void)
+{
+       return must_make_path(runtime_path, BASEDIR, NULL);
+}
+
+static char *get_root_dir(void)
+{
+       return must_make_path(runtime_path, ROOTDIR, NULL);
+}
+
 bool liblxcfs_functional(void)
 {
        return reload_successful != 0;
@@ -580,8 +598,9 @@
 
 static bool umount_if_mounted(void)
 {
-       if (umount2(BASEDIR, MNT_DETACH) < 0 && errno != EINVAL) {
-               lxcfs_error("Failed to unmount %s: %s.\n", BASEDIR, 
strerror(errno));
+       __do_free char *base_dir = get_base_dir();
+       if (umount2(base_dir, MNT_DETACH) < 0 && errno != EINVAL) {
+               lxcfs_error("Failed to unmount %s: %s.\n", base_dir, 
strerror(errno));
                return false;
        }
        return true;
@@ -639,13 +658,14 @@
 static int pivot_enter(void)
 {
        __do_close int oldroot = -EBADF, newroot = -EBADF;
+       __do_free char *root_dir = get_root_dir();
 
        oldroot = open("/", O_DIRECTORY | O_RDONLY | O_CLOEXEC);
        if (oldroot < 0)
                return log_error_errno(-1, errno,
                                       "Failed to open old root for fchdir");
 
-       newroot = open(ROOTDIR, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
+       newroot = open(root_dir, O_DIRECTORY | O_RDONLY | O_CLOEXEC);
        if (newroot < 0)
                return log_error_errno(-1, errno,
                                       "Failed to open new root for fchdir");
@@ -654,7 +674,7 @@
        if (fchdir(newroot) < 0)
                return log_error_errno(-1,
                                       errno, "Failed to change directory to 
new rootfs: %s",
-                                      ROOTDIR);
+                                      root_dir);
 
        /* pivot_root into our new root fs */
        if (pivot_root(".", ".") < 0)
@@ -681,8 +701,10 @@
 
 static int chroot_enter(void)
 {
-       if (mount(ROOTDIR, "/", NULL, MS_REC | MS_BIND, NULL)) {
-               lxcfs_error("Failed to recursively bind-mount %s into /.", 
ROOTDIR);
+       __do_free char *root_dir = get_root_dir();
+
+       if (mount(root_dir, "/", NULL, MS_REC | MS_BIND, NULL)) {
+               lxcfs_error("Failed to recursively bind-mount %s into /.", 
root_dir);
                return -1;
        }
 
@@ -725,23 +747,33 @@
 /* Prepare our new clean root. */
 static int permute_prepare(void)
 {
-       if (mkdir(ROOTDIR, 0700) < 0 && errno != EEXIST) {
+       __do_free char *base_dir = get_base_dir();
+       __do_free char *root_dir = get_root_dir();
+       __do_free char *new_runtime = must_make_path(root_dir, runtime_path, 
NULL);
+       __do_free char *new_base_dir = must_make_path(root_dir, base_dir, NULL);
+
+       if (mkdir(root_dir, 0700) < 0 && errno != EEXIST) {
                lxcfs_error("%s\n", "Failed to create directory for new root.");
                return -1;
        }
 
-       if (mount("/", ROOTDIR, NULL, MS_BIND, 0) < 0) {
+       if (mount("/", root_dir, NULL, MS_BIND, 0) < 0) {
                lxcfs_error("Failed to bind-mount / for new root: %s.\n", 
strerror(errno));
                return -1;
        }
 
-       if (mount(RUNTIME_PATH, ROOTDIR RUNTIME_PATH, NULL, MS_BIND, 0) < 0) {
-               lxcfs_error("Failed to bind-mount /run into new root: %s.\n", 
strerror(errno));
+       if (!mkdir_p(new_runtime, 0700)) {
+               lxcfs_error("Failed to create dir %s\n", new_runtime);
+               return -1;
+       }
+
+       if (mount(runtime_path, new_runtime, NULL, MS_BIND, 0) < 0) {
+               lxcfs_error("Failed to bind-mount %s into new root: %s.\n", 
runtime_path, strerror(errno));
                return -1;
        }
 
-       if (mount(BASEDIR, ROOTDIR BASEDIR, NULL, MS_REC | MS_MOVE, 0) < 0) {
-               printf("Failed to move " BASEDIR " into new root: %s.\n", 
strerror(errno));
+       if (mount(base_dir, new_base_dir, NULL, MS_REC | MS_MOVE, 0) < 0) {
+               printf("Failed to move %s into new root: %s.\n", base_dir, 
strerror(errno));
                return -1;
        }
 
@@ -764,7 +796,9 @@
 
 static bool cgfs_prepare_mounts(void)
 {
-       if (!mkdir_p(BASEDIR, 0700)) {
+       __do_free char *base_dir = get_base_dir();
+
+       if (!mkdir_p(base_dir, 0700)) {
                lxcfs_error("%s\n", "Failed to create lxcfs cgroup 
mountpoint.");
                return false;
        }
@@ -790,7 +824,7 @@
                return false;
        }
 
-       if (mount("tmpfs", BASEDIR, "tmpfs", 0, "size=100000,mode=700") < 0) {
+       if (mount("tmpfs", base_dir, "tmpfs", 0, "size=100000,mode=700") < 0) {
                lxcfs_error("%s\n", "Failed to mount tmpfs over lxcfs cgroup 
mountpoint.");
                return false;
        }
@@ -800,14 +834,17 @@
 
 static bool cgfs_mount_hierarchies(void)
 {
-       if (!mkdir_p(BASEDIR DEFAULT_CGROUP_MOUNTPOINT, 0755))
+       __do_free char *base_dir = get_base_dir();
+       __do_free char *base_dir_cgroup_mount = must_make_path(base_dir, 
DEFAULT_CGROUP_MOUNTPOINT, NULL);
+
+       if (!mkdir_p(base_dir_cgroup_mount, 0700))
                return false;
 
-       if (!cgroup_ops->mount(cgroup_ops, BASEDIR))
+       if (!cgroup_ops->mount(cgroup_ops, base_dir))
                return false;
 
        for (struct hierarchy **h = cgroup_ops->hierarchies; h && *h; h++) {
-               __do_free char *path = must_make_path(BASEDIR, 
(*h)->mountpoint, NULL);
+               __do_free char *path = must_make_path(base_dir, 
(*h)->mountpoint, NULL);
                (*h)->fd = open(path, O_DIRECTORY | O_CLOEXEC | O_NOFOLLOW);
                if ((*h)->fd < 0)
                        return false;
@@ -862,7 +899,19 @@
        return;
 }
 
-static void __attribute__((constructor)) lxcfs_init(void)
+bool set_runtime_path(const char* new_path)
+{
+       if (new_path && strlen(new_path) < PATH_MAX) {
+               strcpy(runtime_path, new_path);
+               lxcfs_info("Using runtime path %s", runtime_path);
+               return true;
+       } else {
+               lxcfs_error("%s\n", "Failed to overwrite the runtime path");
+               return false;
+       }
+}
+
+void lxcfslib_init(void)
 {
        __do_close int init_ns = -EBADF, root_fd = -EBADF,
                                  pidfd = -EBADF;
@@ -871,7 +920,7 @@
        pid_t pid;
        struct hierarchy *hierarchy;
 
-       lxcfs_info("Running constructor %s to reload liblxcfs", __func__);
+       lxcfs_info("Running %s to reload liblxcfs", __func__);
 
        cgroup_ops = cgroup_init();
        if (!cgroup_ops) {
@@ -971,9 +1020,20 @@
 void *lxcfs_fuse_init(struct fuse_conn_info *conn, void *data)
 {
        struct fuse_context *fc = fuse_get_context();
+       struct lxcfs_opts *opts = fc ? fc->private_data : NULL;
+
 #if HAVE_FUSE_RETURNS_DT_TYPE
        can_use_sys_cpu = true;
 #endif
        has_versioned_opts = true;
-       return fc ? fc->private_data : NULL;
+
+       // We can read runtime_path as of opts version 2.
+       if (opts && opts->version >= 2) {
+               set_runtime_path(opts->runtime_path);
+       }
+
+       /* initialize the library */
+       lxcfslib_init();
+
+       return opts;
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/src/bindings.h 
new/lxcfs-6.0.1/src/bindings.h
--- old/lxcfs-6.0.0/src/bindings.h      2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/src/bindings.h      2024-06-26 04:31:57.000000000 +0200
@@ -23,10 +23,6 @@
 #include "proc_loadavg.h"
 #include "sysfs_fuse.h"
 
-/* directory under which we mount the controllers - /run/lxcfs/controllers */
-#define BASEDIR RUNTIME_PATH "/lxcfs/controllers"
-#define ROOTDIR RUNTIME_PATH "/lxcfs/root"
-
 /* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 
*/
 #define LXCFS_NUMSTRLEN64 21
 
@@ -116,6 +112,8 @@
         * and the use of bool instead of explicited __u32 and __u64 we can't.
         */
        __u32 version;
+        // As of opts version 2.
+        char runtime_path[PATH_MAX];
 };
 
 typedef enum lxcfs_opt_t {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/src/lxcfs.c new/lxcfs-6.0.1/src/lxcfs.c
--- old/lxcfs-6.0.0/src/lxcfs.c 2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/src/lxcfs.c 2024-06-26 04:31:57.000000000 +0200
@@ -32,7 +32,11 @@
 #include "macro.h"
 #include "memory_utils.h"
 
+#define PID_FILE "/lxcfs.pid"
+
 void *dlopen_handle;
+static char runtime_path[PATH_MAX] = DEFAULT_RUNTIME_PATH;
+
 
 /* Functions to keep track of number of threads using the library */
 
@@ -146,7 +150,7 @@
 
 static volatile sig_atomic_t need_reload;
 
-static int lxcfs_init_library(void)
+static int do_lxcfs_fuse_init(void)
 {
        char *error;
        void *(*__lxcfs_fuse_init)(struct fuse_conn_info * conn, void * cfg);
@@ -199,13 +203,12 @@
 
         dlopen_handle = dlopen(lxcfs_lib_path, RTLD_LAZY);
        if (!dlopen_handle)
-               log_exit("%s - Failed to open liblxcfs.so", dlerror());
+               log_exit("%s - Failed to open liblxcfs.so at %s", dlerror(), 
lxcfs_lib_path);
        else
                lxcfs_debug("Opened %s", lxcfs_lib_path);
 
 good:
-       /* initialize the library */
-       if (reinit && lxcfs_init_library() < 0) {
+       if (reinit && do_lxcfs_fuse_init() < 0) {
                log_exit("Failed to initialize liblxcfs.so");
        }
 
@@ -1119,7 +1122,7 @@
 static void *lxcfs_init(struct fuse_conn_info *conn)
 #endif
 {
-       if (lxcfs_init_library() < 0)
+       if (do_lxcfs_fuse_init() < 0)
                return NULL;
 
 #if HAVE_FUSE3
@@ -1187,12 +1190,14 @@
        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("                       Default pidfile is %s/lxcfs.pid", 
DEFAULT_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("  --enable-cgroup      Enable cgroup emulation code");
+       lxcfs_info("  --runtime-dir=DIR    Path to use as the runtime 
directory.");
+       lxcfs_info("                       Default is %s", 
DEFAULT_RUNTIME_PATH);
        exit(EXIT_FAILURE);
 }
 
@@ -1244,6 +1249,7 @@
        {"enable-cgroup",       no_argument,            0,        0     },
 
        {"pidfile",             required_argument,      0,      'p'     },
+       {"runtime-dir",         required_argument,      0,        0     },
        {                                                               },
 };
 
@@ -1286,7 +1292,7 @@
        int pidfile_fd = -EBADF;
        int ret = EXIT_FAILURE;
        char *pidfile = NULL, *token = NULL;
-       char pidfile_buf[STRLITERALLEN(RUNTIME_PATH) + 
STRLITERALLEN("/lxcfs.pid") + 1] = {};
+       char pidfile_buf[PATH_MAX + sizeof(PID_FILE)] = {};
        bool debug = false, foreground = false;
 #if !HAVE_FUSE3
        bool nonempty = false;
@@ -1303,6 +1309,7 @@
        char *new_fuse_opts = NULL;
        char *const *new_argv;
        struct lxcfs_opts *opts;
+       char *runtime_path_arg = NULL;
 
        opts = malloc(sizeof(struct lxcfs_opts));
        if (opts == NULL) {
@@ -1313,7 +1320,7 @@
        opts->swap_off = false;
        opts->use_pidfd = false;
        opts->use_cfs = false;
-       opts->version = 1;
+       opts->version = 2;
 
        while ((c = getopt_long(argc, argv, "dulfhvso:p:", long_options, &idx)) 
!= -1) {
                switch (c) {
@@ -1324,6 +1331,8 @@
                                opts->use_cfs = true;
                        else if (strcmp(long_options[idx].name, 
"enable-cgroup") == 0)
                                cgroup_is_enabled = true;
+                       else if (strcmp(long_options[idx].name, "runtime-dir") 
== 0)
+                               runtime_path_arg = optarg;
                        else
                                usage();
                        break;
@@ -1376,6 +1385,12 @@
                goto out;
        }
 
+       if (runtime_path_arg) {
+               strcpy(runtime_path, runtime_path_arg);
+               lxcfs_info("runtime path set to %s", runtime_path);
+       }
+       strcpy(opts->runtime_path, runtime_path);
+
        fuse_argv[fuse_argc++] = argv[0];
        if (debug)
                fuse_argv[fuse_argc++] = "-d";
@@ -1467,6 +1482,7 @@
        lxcfs_info("Starting LXCFS at %s", argv[0]);
 
        do_reload(false);
+
        if (install_signal_handler(SIGUSR1, sigusr1_reload)) {
                lxcfs_error("%s - Failed to install SIGUSR1 signal handler", 
strerror(errno));
                goto out;
@@ -1480,7 +1496,7 @@
 #endif
 
        if (!pidfile) {
-               snprintf(pidfile_buf, sizeof(pidfile_buf), "%s/lxcfs.pid", 
RUNTIME_PATH);
+               snprintf(pidfile_buf, sizeof(pidfile_buf), "%s%s", 
runtime_path, PID_FILE);
                pidfile = pidfile_buf;
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/src/proc_fuse.c 
new/lxcfs-6.0.1/src/proc_fuse.c
--- old/lxcfs-6.0.0/src/proc_fuse.c     2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/src/proc_fuse.c     2024-06-26 04:31:57.000000000 +0200
@@ -145,8 +145,11 @@
            strcmp(path, "/proc/swaps")         == 0 ||
            strcmp(path, "/proc/loadavg")       == 0 ||
            strcmp(path, "/proc/slabinfo")      == 0) {
-               if (liblxcfs_functional())
+               if (liblxcfs_functional()) {
+                       if (!can_access_personality())
+                               return log_error(-EACCES, 
RESTRICTED_PERSONALITY_ACCESS_POLICY);
                        sb->st_size = get_procfile_size_with_personality(path);
+               }
                else
                        sb->st_size = get_procfile_size(path);
                sb->st_mode = S_IFREG | 00444;
@@ -206,8 +209,11 @@
 
        info->type = type;
 
-       if (liblxcfs_functional())
+       if (liblxcfs_functional()) {
+               if (!can_access_personality())
+                       return log_error(-EACCES, 
RESTRICTED_PERSONALITY_ACCESS_POLICY);
                info->buflen = get_procfile_size_with_personality(path) + 
BUF_RESERVE_SIZE;
+       }
        else
                info->buflen = get_procfile_size(path) + BUF_RESERVE_SIZE;
 
@@ -1646,8 +1652,11 @@
                return read_file_fuse_with_offset(LXC_TYPE_PROC_MEMINFO_PATH,
                                                  buf, size, offset, f);
        case LXC_TYPE_PROC_CPUINFO:
-               if (liblxcfs_functional())
+               if (liblxcfs_functional()) {
+                       if (!can_access_personality())
+                               return log_error(-EACCES, 
RESTRICTED_PERSONALITY_ACCESS_POLICY);
                        return proc_read_with_personality(&proc_cpuinfo_read, 
buf, size, offset, fi);
+               }
 
                return read_file_fuse_with_offset(LXC_TYPE_PROC_CPUINFO_PATH,
                                                  buf, size, offset, f);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/src/utils.c new/lxcfs-6.0.1/src/utils.c
--- old/lxcfs-6.0.0/src/utils.c 2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/src/utils.c 2024-06-26 04:31:57.000000000 +0200
@@ -685,9 +685,31 @@
        ret = read_nointr(fd, buf, sizeof(buf) - 1);
        if (ret >= 0) {
                buf[ret] = '\0';
-               if (safe_uint32(buf, personality, 16) < 0)
+               if (personality != NULL && safe_uint32(buf, personality, 16) < 
0)
                        return log_error(-1, "Failed to convert personality 
%s", buf);
        }
 
        return ret;
 }
+
+/*
+       This function checks whether system security policy (i.e. Yama LSM) 
allows personality access, by trying on
+       init own one.
+       This is required as it may be restricted by a ptrace access mode check 
(see PROC(5)), and
+       `get_task_personality` function relies on this.
+*/
+bool can_access_personality(void)
+{
+       static int could_access_init_personality = -1;
+
+       /* init personality has never been accessed (cache is empty) */
+       if (could_access_init_personality == -1) {
+               if (get_task_personality(1, NULL) < 0) {
+                       could_access_init_personality = 0;
+               } else {
+                       could_access_init_personality = 1;
+               }
+       }
+
+       return could_access_init_personality != 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/src/utils.h new/lxcfs-6.0.1/src/utils.h
--- old/lxcfs-6.0.0/src/utils.h 2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/src/utils.h 2024-06-26 04:31:57.000000000 +0200
@@ -25,6 +25,8 @@
 #define SEND_CREDS_NOTSK 1
 #define SEND_CREDS_FAIL 2
 
+#define RESTRICTED_PERSONALITY_ACCESS_POLICY "Due to restricted personality 
access policy, reading proc files from containers is not permitted"
+
 struct file_info;
 
 __attribute__((__format__(__printf__, 4, 5))) extern char *must_strcat(char 
**src, size_t *sz, size_t *asz, const char *format, ...);
@@ -77,6 +79,7 @@
 extern char *read_file_at(int dfd, const char *fnam, unsigned int o_flags);
 
 extern int get_task_personality(pid_t pid, __u32 *personality);
+extern bool can_access_personality(void);
 extern int get_host_personality(__u32 *personality);
 
 #endif /* __LXCFS_UTILS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/tests/live-upgrade-test.sh.in 
new/lxcfs-6.0.1/tests/live-upgrade-test.sh.in
--- old/lxcfs-6.0.0/tests/live-upgrade-test.sh.in       1970-01-01 
01:00:00.000000000 +0100
+++ new/lxcfs-6.0.1/tests/live-upgrade-test.sh.in       2024-06-26 
04:31:57.000000000 +0200
@@ -0,0 +1,143 @@
+#!/bin/sh
+# SPDX-License-Identifier: LGPL-2.1+
+
+set -eu
+[ -n "${DEBUG:-}" ] && set -x
+
+[ $(id -u) -eq 0 ]
+
+NEW_LXCFS_TREE=$1
+
+echo "LXCFS trees:"
+pwd
+echo "${NEW_LXCFS_TREE}"
+
+# Run lxcfs testsuite
+export LXCFSDIR=$(mktemp -d)
+pidfile=$(mktemp)
+export LXCFSPID=-1
+
+cmdline=$(realpath $0)
+dirname=$(dirname ${cmdline})
+
+FAILED=1
+UNSHARE=1
+cleanup() {
+       echo "=> Cleaning up"
+       set +e
+       if [ $LXCFSPID -ne -1 ]; then
+               kill -9 $LXCFSPID
+       fi
+       if [ ${LXCFSDIR} != "/var/lib/lxcfs" ]; then
+               umount -l ${LXCFSDIR}
+               rmdir ${LXCFSDIR}
+       fi
+       rm -f ${pidfile}
+       if [ ${FAILED} -eq 1 ]; then
+               echo "=> FAILED at $TESTCASE"
+               exit 1
+       fi
+       echo "=> PASSED"
+       exit 0
+}
+
+TESTCASE="setup"
+lxcfs="{{LXCFS_BUILD_ROOT}}/lxcfs"
+
+if [ -x ${lxcfs} ]; then
+       if [ -n "${LD_LIBRARY_PATH:-}" ]; then
+               export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}:${LD_LIBRARY_PATH}"
+       else
+               export LD_LIBRARY_PATH="{{LXCFS_BUILD_ROOT}}"
+       fi
+       echo "=> Spawning ${lxcfs} ${LXCFSDIR}"
+       ${lxcfs} --enable-cgroup -p ${pidfile} ${LXCFSDIR} &
+       LXCFSPID=$!
+else
+       UNSHARE=0
+       LXCFSPID=$(cat "{{DEFAULT_RUNTIME_PATH}}/lxcfs.pid")
+       echo "=> Re-using host lxcfs"
+       rmdir $LXCFSDIR
+       export LXCFSDIR=/var/lib/lxcfs
+fi
+
+trap cleanup EXIT HUP INT TERM
+
+count=1
+while ! mountpoint -q $LXCFSDIR; do
+       sleep 1s
+       if [ $count -gt 5 ]; then
+               echo "lxcfs failed to start"
+               false
+       fi
+       count=$((count+1))
+done
+
+RUNTEST() {
+       echo ""
+       echo "=> Running ${TESTCASE}"
+
+       if [ "${UNSHARE:-1}" != "0" ]; then
+               unshare -fmp --mount-proc $*
+       else
+               $*
+       fi
+}
+
+RUNTESTS() {
+       TESTCASE="Stress readdir"
+       RUNTEST ${dirname}/test_readdir
+       TESTCASE="test_proc"
+       RUNTEST ${dirname}/test_proc
+       TESTCASE="test_cgroup"
+       RUNTEST ${dirname}/test_cgroup
+       TESTCASE="test_read_proc.sh"
+       RUNTEST ${dirname}/test_read_proc.sh
+       TESTCASE="cpusetrange"
+       RUNTEST ${dirname}/test-cpusetrange
+       TESTCASE="meminfo hierarchy"
+       RUNTEST ${dirname}/test_meminfo_hierarchy.sh
+
+       TESTCASE="SIGUSR2 virtualization mode switching"
+       echo "==> Switching to non-virtualization mode"
+       kill -USR2 $LXCFSPID
+       RUNTEST ${dirname}/test_sigusr2.sh
+       echo "==> Switching to virtualization mode"
+       kill -USR2 $LXCFSPID
+}
+
+echo ""
+echo "=> Running tests BEFORE reload"
+RUNTESTS
+
+TESTCASE="liblxcfs reloading (with upgrade)"
+
+rm -f /tmp/lxcfs-iwashere
+
+echo "==> Ensure that lxcfs is functional BEFORE reload"
+cat ${LXCFSDIR}/proc/uptime
+
+libdir="{{LXCFS_BUILD_ROOT}}"
+
+[ ! -f /tmp/lxcfs-iwashere ]
+rm -f ${libdir}/liblxcfs.so ${libdir}/liblxcfs.la
+cp ${NEW_LXCFS_TREE}/build/liblxcfstest.so ${libdir}/liblxcfs.so
+
+echo "==> Reload liblxcfs"
+kill -USR1 $LXCFSPID
+sleep 1
+
+echo "==> Ensure that lxcfs is functional AFTER reload"
+cat ${LXCFSDIR}/proc/uptime
+sleep 1
+[ -f /tmp/lxcfs-iwashere ]
+
+echo ""
+echo "=> Running tests AFTER reload"
+RUNTESTS
+
+# Check for any defunct processes - children we didn't reap
+n=`ps -ef | grep lxcfs | grep defunct | wc -l`
+[ $n = 0 ]
+
+FAILED=0
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/tests/main.sh.in 
new/lxcfs-6.0.1/tests/main.sh.in
--- old/lxcfs-6.0.0/tests/main.sh.in    2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/tests/main.sh.in    2024-06-26 04:31:57.000000000 +0200
@@ -49,7 +49,7 @@
        LXCFSPID=$!
 else
        UNSHARE=0
-       LXCFSPID=$(cat "{{RUNTIME_PATH}}/lxcfs.pid")
+       LXCFSPID=$(cat "{{DEFAULT_RUNTIME_PATH}}/lxcfs.pid")
        echo "=> Re-using host lxcfs"
        rmdir $LXCFSDIR
        export LXCFSDIR=/var/lib/lxcfs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-6.0.0/tests/meson.build 
new/lxcfs-6.0.1/tests/meson.build
--- old/lxcfs-6.0.0/tests/meson.build   2024-03-28 03:44:27.000000000 +0100
+++ new/lxcfs-6.0.1/tests/meson.build   2024-06-26 04:31:57.000000000 +0200
@@ -13,6 +13,18 @@
     ])
 
 test_programs += custom_target(
+   'live-upgrade-test.sh',
+    build_by_default: want_tests != false,
+    input: 'live-upgrade-test.sh.in',
+    output: 'live-upgrade-test.sh',
+    command: [
+        meson_render_jinja2,
+        config_h,
+        '@INPUT@',
+        '@OUTPUT@',
+    ])
+
+test_programs += custom_target(
     'test_cgroup',
     build_by_default: want_tests != false,
     input: 'test_cgroup.in',

Reply via email to