Hello community,

here is the log from the commit of package lxcfs for openSUSE:Factory checked 
in at 2020-05-11 13:43:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/lxcfs (Old)
 and      /work/SRC/openSUSE:Factory/.lxcfs.new.2738 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "lxcfs"

Mon May 11 13:43:27 2020 rev:13 rq:802545 version:4.0.3

Changes:
--------
--- /work/SRC/openSUSE:Factory/lxcfs/lxcfs.changes      2020-04-27 
23:42:28.388007241 +0200
+++ /work/SRC/openSUSE:Factory/.lxcfs.new.2738/lxcfs.changes    2020-05-11 
13:43:34.821402967 +0200
@@ -1,0 +2,7 @@
+Sun May 10 05:58:58 UTC 2020 - Pavol Cupka <pal...@liguros.net>
+
+- update to LXCFS 4.0.3 (released on the 17th of April 2020)
+  detailed changelog:
+  https://discuss.linuxcontainers.org/t/lxcfs-4-0-3-lts-has-been-released/7470 
+
+-------------------------------------------------------------------

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

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

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

Other differences:
------------------
++++++ lxcfs.spec ++++++
--- /var/tmp/diff_new_pack.EwT0zv/_old  2020-05-11 13:43:36.313406133 +0200
+++ /var/tmp/diff_new_pack.EwT0zv/_new  2020-05-11 13:43:36.317406142 +0200
@@ -22,7 +22,7 @@
 %endif
 
 Name:           lxcfs
-Version:        4.0.1
+Version:        4.0.3
 Release:        0
 Summary:        FUSE filesystem for LXC
 License:        Apache-2.0

++++++ lxcfs-4.0.1.tar.gz -> lxcfs-4.0.3.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/config/init/systemd/Makefile.in 
new/lxcfs-4.0.3/config/init/systemd/Makefile.in
--- old/lxcfs-4.0.1/config/init/systemd/Makefile.in     2020-03-19 
15:21:45.000000000 +0100
+++ new/lxcfs-4.0.3/config/init/systemd/Makefile.in     2020-04-17 
22:15:45.000000000 +0200
@@ -370,8 +370,8 @@
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
        @echo "it deletes files that may require special tools to rebuild."
-@INIT_SCRIPT_SYSTEMD_FALSE@uninstall-local:
 @INIT_SCRIPT_SYSTEMD_FALSE@install-data-local:
+@INIT_SCRIPT_SYSTEMD_FALSE@uninstall-local:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool mostlyclean-am
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/config/init/upstart/Makefile.in 
new/lxcfs-4.0.3/config/init/upstart/Makefile.in
--- old/lxcfs-4.0.1/config/init/upstart/Makefile.in     2020-03-19 
15:21:45.000000000 +0100
+++ new/lxcfs-4.0.3/config/init/upstart/Makefile.in     2020-04-17 
22:15:45.000000000 +0200
@@ -367,8 +367,8 @@
 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
        @echo "it deletes files that may require special tools to rebuild."
-@INIT_SCRIPT_UPSTART_FALSE@install-data-local:
 @INIT_SCRIPT_UPSTART_FALSE@uninstall-local:
+@INIT_SCRIPT_UPSTART_FALSE@install-data-local:
 clean: clean-am
 
 clean-am: clean-generic clean-libtool mostlyclean-am
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/config/ltmain.sh 
new/lxcfs-4.0.3/config/ltmain.sh
--- old/lxcfs-4.0.1/config/ltmain.sh    2020-02-16 13:06:34.000000000 +0100
+++ new/lxcfs-4.0.3/config/ltmain.sh    2020-03-02 10:35:42.000000000 +0100
@@ -31,7 +31,7 @@
 
 PROGRAM=libtool
 PACKAGE=libtool
-VERSION="2.4.6 Debian-2.4.6-13"
+VERSION="2.4.6 Debian-2.4.6-14"
 package_revision=2.4.6
 
 
@@ -2141,7 +2141,7 @@
        compiler:       $LTCC
        compiler flags: $LTCFLAGS
        linker:         $LD (gnu? $with_gnu_ld)
-       version:        $progname $scriptversion Debian-2.4.6-13
+       version:        $progname $scriptversion Debian-2.4.6-14
        automake:       `($AUTOMAKE --version) 2>/dev/null |$SED 1q`
        autoconf:       `($AUTOCONF --version) 2>/dev/null |$SED 1q`
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/configure new/lxcfs-4.0.3/configure
--- old/lxcfs-4.0.1/configure   2020-03-19 15:21:44.000000000 +0100
+++ new/lxcfs-4.0.3/configure   2020-04-17 22:15:44.000000000 +0200
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for lxcfs 4.0.1.
+# Generated by GNU Autoconf 2.69 for lxcfs 4.0.3.
 #
 # Report bugs to <lxc-de...@lists.linuxcontainers.org>.
 #
@@ -590,8 +590,8 @@
 # Identity of this package.
 PACKAGE_NAME='lxcfs'
 PACKAGE_TARNAME='lxcfs'
-PACKAGE_VERSION='4.0.1'
-PACKAGE_STRING='lxcfs 4.0.1'
+PACKAGE_VERSION='4.0.3'
+PACKAGE_STRING='lxcfs 4.0.3'
 PACKAGE_BUGREPORT='lxc-de...@lists.linuxcontainers.org'
 PACKAGE_URL=''
 
@@ -1377,7 +1377,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures lxcfs 4.0.1 to adapt to many kinds of systems.
+\`configure' configures lxcfs 4.0.3 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1448,7 +1448,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of lxcfs 4.0.1:";;
+     short | recursive ) echo "Configuration of lxcfs 4.0.3:";;
    esac
   cat <<\_ACEOF
 
@@ -1576,7 +1576,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-lxcfs configure 4.0.1
+lxcfs configure 4.0.3
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1945,7 +1945,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by lxcfs $as_me 4.0.1, which was
+It was created by lxcfs $as_me 4.0.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -2938,7 +2938,7 @@
 
 # Define the identity of the package.
  PACKAGE='lxcfs'
- VERSION='4.0.1'
+ VERSION='4.0.3'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -14985,7 +14985,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by lxcfs $as_me 4.0.1, which was
+This file was extended by lxcfs $as_me 4.0.3, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15051,7 +15051,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; 
s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-lxcfs config.status 4.0.1
+lxcfs config.status 4.0.3
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/configure.ac new/lxcfs-4.0.3/configure.ac
--- old/lxcfs-4.0.1/configure.ac        2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/configure.ac        2020-04-17 22:15:36.000000000 +0200
@@ -1,6 +1,6 @@
 AC_PREREQ([2.69])
 
-AC_INIT([lxcfs], [4.0.1], [lxc-de...@lists.linuxcontainers.org])
+AC_INIT([lxcfs], [4.0.3], [lxc-de...@lists.linuxcontainers.org])
 
 # We need pkg-config
 PKG_PROG_PKG_CONFIG
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/lxcfs.spec new/lxcfs-4.0.3/lxcfs.spec
--- old/lxcfs-4.0.1/lxcfs.spec  2020-03-19 15:21:50.000000000 +0100
+++ new/lxcfs-4.0.3/lxcfs.spec  2020-04-17 22:15:51.000000000 +0200
@@ -20,7 +20,7 @@
 
 Summary: Linux Containers File System
 Name: lxcfs
-Version: 4.0.1
+Version: 4.0.3
 Release: 1%{?dist}
 URL: https://linuxcontainers.org/lxcfs/downloads/
 Source0: %{name}-%{version}.tar.gz
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/Makefile.am 
new/lxcfs-4.0.3/src/Makefile.am
--- old/lxcfs-4.0.1/src/Makefile.am     2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/Makefile.am     2020-04-17 22:15:36.000000000 +0200
@@ -20,6 +20,7 @@
                      proc_cpuview.c proc_cpuview.h \
                      proc_fuse.c proc_fuse.h \
                      proc_loadavg.c proc_loadavg.h \
+                     syscall_numbers.h \
                      sysfs_fuse.c sysfs_fuse.h \
                      utils.c utils.h
 liblxcfs_la_CFLAGS = $(AM_CFLAGS)
@@ -48,6 +49,7 @@
                          proc_cpuview.c proc_cpuview.h \
                          proc_fuse.c proc_fuse.h \
                          proc_loadavg.c proc_loadavg.h \
+                         syscall_numbers.h \
                          sysfs_fuse.c sysfs_fuse.h \
                          utils.c utils.h
 liblxcfstest_la_CFLAGS = $(AM_CFLAGS) -DRELOADTEST
@@ -75,6 +77,7 @@
                 proc_cpuview.h \
                 proc_fuse.h \
                 proc_loadavg.h \
+                syscall_numbers.h \
                 sysfs_fuse.h \
                 utils.h
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/Makefile.in 
new/lxcfs-4.0.3/src/Makefile.in
--- old/lxcfs-4.0.1/src/Makefile.in     2020-03-19 15:21:45.000000000 +0100
+++ new/lxcfs-4.0.3/src/Makefile.in     2020-04-17 22:15:45.000000000 +0200
@@ -424,6 +424,7 @@
                      proc_cpuview.c proc_cpuview.h \
                      proc_fuse.c proc_fuse.h \
                      proc_loadavg.c proc_loadavg.h \
+                     syscall_numbers.h \
                      sysfs_fuse.c sysfs_fuse.h \
                      utils.c utils.h
 
@@ -442,6 +443,7 @@
                          proc_cpuview.c proc_cpuview.h \
                          proc_fuse.c proc_fuse.h \
                          proc_loadavg.c proc_loadavg.h \
+                         syscall_numbers.h \
                          sysfs_fuse.c sysfs_fuse.h \
                          utils.c utils.h
 
@@ -460,6 +462,7 @@
                 proc_cpuview.h \
                 proc_fuse.h \
                 proc_loadavg.h \
+                syscall_numbers.h \
                 sysfs_fuse.h \
                 utils.h
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/bindings.c 
new/lxcfs-4.0.3/src/bindings.c
--- old/lxcfs-4.0.1/src/bindings.c      2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/bindings.c      2020-04-17 22:15:36.000000000 +0200
@@ -46,6 +46,7 @@
 #include "config.h"
 #include "memory_utils.h"
 #include "proc_cpuview.h"
+#include "syscall_numbers.h"
 #include "utils.h"
 
 static bool can_use_pidfd;
@@ -61,12 +62,7 @@
 #ifndef HAVE_PIVOT_ROOT
 static int pivot_root(const char *new_root, const char *put_old)
 {
-#ifdef __NR_pivot_root
        return syscall(__NR_pivot_root, new_root, put_old);
-#else
-       errno = ENOSYS;
-       return -1;
-#endif
 }
 #else
 extern int pivot_root(const char *new_root, const char *put_old);
@@ -122,14 +118,17 @@
                log_exit("%s - returned %d\n", strerror(ret), ret);
 }
 
-static void store_lock(void)
+static inline void unlock_mutex_function(pthread_mutex_t **mutex)
 {
-       lock_mutex(&pidns_store_mutex);
+       if (*mutex)
+               unlock_mutex(*mutex);
 }
+#define __do_unlock call_cleaner(unlock_mutex)
 
-static void store_unlock(void)
+static pthread_mutex_t* __attribute__((warn_unused_result)) store_lock(void)
 {
-       unlock_mutex(&pidns_store_mutex);
+       lock_mutex(&pidns_store_mutex);
+       return &pidns_store_mutex;
 }
 
 /* /proc/       =    6
@@ -256,7 +255,7 @@
 }
 
 /* Must be called under store_lock */
-static void save_initpid(struct stat *sb, pid_t pid)
+static void save_initpid(ino_t pidns_inode, pid_t pid)
 {
        __do_free struct pidns_init_store *entry = NULL;
        __do_close int pidfd = -EBADF;
@@ -275,13 +274,13 @@
        if (stat(path, &st))
                return;
 
-       entry = malloc(sizeof(*entry));
-       if (entry)
+       entry = zalloc(sizeof(*entry));
+       if (!entry)
                return;
 
        ino_hash = HASH(entry->ino);
        *entry = (struct pidns_init_store){
-               .ino            = sb->st_ino,
+               .ino            = pidns_inode,
                .initpid        = pid,
                .ctime          = st.st_ctime,
                .next           = pidns_hash_table[ino_hash],
@@ -300,12 +299,12 @@
  * otherwise.
  * Must be called under store_lock
  */
-static struct pidns_init_store *lookup_verify_initpid(struct stat *sb)
+static struct pidns_init_store *lookup_verify_initpid(ino_t pidns_inode)
 {
-       struct pidns_init_store *entry = pidns_hash_table[HASH(sb->st_ino)];
+       struct pidns_init_store *entry = pidns_hash_table[HASH(pidns_inode)];
 
        while (entry) {
-               if (entry->ino == sb->st_ino) {
+               if (entry->ino == pidns_inode) {
                        if (initpid_still_valid(entry)) {
                                entry->lastcheck = time(NULL);
                                return entry;
@@ -338,7 +337,7 @@
  * stack sizes: 8MB.
  */
 #define __LXCFS_STACK_SIZE (8 * 1024 * 1024)
-static pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags)
+pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags)
 {
        pid_t ret;
        void *stack;
@@ -399,9 +398,13 @@
 {
        char v = '0';
        pid_t pid_ret = -1;
+       struct ucred cred = {
+               .pid = -1,
+               .uid = -1,
+               .gid = -1,
+       };
        pid_t pid;
        int sock[2];
-       struct ucred cred;
 
        if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sock) < 0)
                return -1;
@@ -432,6 +435,7 @@
 
 pid_t lookup_initpid_in_store(pid_t pid)
 {
+       __do_unlock pthread_mutex_t *store_mutex = NULL;
        pid_t answer = 0;
        char path[LXCFS_PROC_PID_NS_LEN];
        struct stat st;
@@ -439,19 +443,24 @@
 
        snprintf(path, sizeof(path), "/proc/%d/ns/pid", pid);
 
-       store_lock();
        if (stat(path, &st))
                goto out;
 
-       entry = lookup_verify_initpid(&st);
+       store_mutex = store_lock();
+
+       entry = lookup_verify_initpid(st.st_ino);
        if (entry) {
                answer = entry->initpid;
                goto out;
        }
 
+       /* release the mutex as the following call is expensive */
+       unlock_mutex(move_ptr(store_mutex));
        answer = get_init_pid_for_task(pid);
+       store_mutex = store_lock();
+
        if (answer > 0)
-               save_initpid(&st, answer);
+               save_initpid(st.st_ino, answer);
 
 out:
        /*
@@ -460,8 +469,6 @@
         */
        prune_initpid_store();
 
-       store_unlock();
-
        return answer;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/bindings.h 
new/lxcfs-4.0.3/src/bindings.h
--- old/lxcfs-4.0.1/src/bindings.h      2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/bindings.h      2020-04-17 22:15:36.000000000 +0200
@@ -103,4 +103,6 @@
        return sigaction(signo, &action, NULL);
 }
 
+extern pid_t lxcfs_clone(int (*fn)(void *), void *arg, int flags);
+
 #endif /* __LXCFS_BINDINGS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroup_fuse.c 
new/lxcfs-4.0.3/src/cgroup_fuse.c
--- old/lxcfs-4.0.1/src/cgroup_fuse.c   2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/cgroup_fuse.c   2020-04-17 22:15:36.000000000 +0200
@@ -62,7 +62,7 @@
 
 static inline int get_cgroup_fd_handle_named(const char *controller)
 {
-       if (strcmp(controller, "systemd") == 0)
+       if (controller && strcmp(controller, "systemd") == 0)
                return get_cgroup_fd("name=systemd");
 
        return get_cgroup_fd(controller);
@@ -70,7 +70,7 @@
 
 static char *get_pid_cgroup_handle_named(pid_t pid, const char *controller)
 {
-       if (strcmp(controller, "systemd") == 0)
+       if (controller && strcmp(controller, "systemd") == 0)
                return get_pid_cgroup(pid, "name=systemd");
 
        return get_pid_cgroup(pid, controller);
@@ -80,7 +80,7 @@
                                    const char *controller, const char *cgroup,
                                    const char *file, char **value)
 {
-       if (strcmp(controller, "systemd") == 0)
+       if (controller && strcmp(controller, "systemd") == 0)
                return cgroup_ops->get(ops, "name=systemd", cgroup, file, 
value);
 
        return cgroup_ops->get(cgroup_ops, controller, cgroup, file, value);
@@ -268,9 +268,10 @@
 static bool caller_is_in_ancestor(pid_t pid, const char *contrl, const char 
*cg, char **nextcg)
 {
        bool answer = false;
-       char *c2 = get_pid_cgroup_handle_named(pid, contrl);
+       char *c2;
        char *linecmp;
 
+       c2 = get_pid_cgroup_handle_named(pid, contrl);
        if (!c2)
                return false;
        prune_init_slice(c2);
@@ -745,22 +746,22 @@
 
 static bool recursive_rmdir(const char *dirname, int fd, const int cfd)
 {
-       struct dirent *direntp;
-       DIR *dir;
+       __do_close int dupfd = -EBADF;
+       __do_closedir DIR *dir = NULL;
        bool ret = false;
+       struct dirent *direntp;
        char pathname[MAXPATHLEN];
-       int dupfd;
 
-       dupfd = dup(fd); // fdopendir() does bad things once it uses an fd.
+       dupfd = dup(fd);
        if (dupfd < 0)
                return false;
 
        dir = fdopendir(dupfd);
        if (!dir) {
                lxcfs_debug("Failed to open %s: %s.\n", dirname, 
strerror(errno));
-               close(dupfd);
                return false;
        }
+       move_fd(dupfd);
 
        while ((direntp = readdir(dir))) {
                struct stat mystat;
@@ -787,18 +788,12 @@
        }
 
        ret = true;
-       if (closedir(dir) < 0) {
-               lxcfs_error("Failed to close directory %s: %s\n", dirname, 
strerror(errno));
-               ret = false;
-       }
 
        if (unlinkat(cfd, dirname, AT_REMOVEDIR) < 0) {
                lxcfs_debug("Failed to delete %s: %s.\n", dirname, 
strerror(errno));
                ret = false;
        }
 
-       close(dupfd);
-
        return ret;
 }
 
@@ -1163,13 +1158,17 @@
 static int pid_to_ns(int sock, pid_t tpid)
 {
        char v = '0';
-       struct ucred cred;
+       struct ucred cred = {
+               .pid = -1,
+               .uid = -1,
+               .gid = -1,
+       };
 
        while (recv_creds(sock, &cred, &v)) {
                if (v == '1')
                        return 0;
 
-               if (write(sock, &cred.pid, sizeof(pid_t)) != sizeof(pid_t))
+               if (write_nointr(sock, &cred.pid, sizeof(pid_t)) != 
sizeof(pid_t))
                        return 1;
        }
 
@@ -1229,10 +1228,8 @@
                .tpid = tpid,
                .wrapped = &pid_to_ns
        };
-       size_t stack_size = sysconf(_SC_PAGESIZE);
-       void *stack = alloca(stack_size);
 
-       cpid = clone(pid_ns_clone_wrapper, stack + stack_size, SIGCHLD, &args);
+       cpid = lxcfs_clone(pid_ns_clone_wrapper, &args, 0);
        if (cpid < 0)
                _exit(1);
 
@@ -1568,10 +1565,8 @@
                .tpid = tpid,
                .wrapped = &pid_from_ns
        };
-       size_t stack_size = sysconf(_SC_PAGESIZE);
-       void *stack = alloca(stack_size);
 
-       cpid = clone(pid_ns_clone_wrapper, stack + stack_size, SIGCHLD, &args);
+       cpid = lxcfs_clone(pid_ns_clone_wrapper, &args, 0);
        if (cpid < 0)
                _exit(1);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroups/cgfsng.c 
new/lxcfs-4.0.3/src/cgroups/cgfsng.c
--- old/lxcfs-4.0.1/src/cgroups/cgfsng.c        2020-03-19 15:21:36.000000000 
+0100
+++ new/lxcfs-4.0.3/src/cgroups/cgfsng.c        2020-04-17 22:15:36.000000000 
+0200
@@ -547,7 +547,7 @@
 {
        __do_free char *path = NULL;
        struct hierarchy *h;
-       int ret;
+       int cgroup2_root_fd, layout, ret;
 
        h = ops->get_hierarchy(ops, "memory");
        if (!h)
@@ -562,17 +562,24 @@
                        file = "memory.memsw.usage_in_bytes";
                else if (strcmp(file, "memory.current") == 0)
                        file = "memory.usage_in_bytes";
-               ret = CGROUP_SUPER_MAGIC;
+               layout = CGROUP_SUPER_MAGIC;
+               cgroup2_root_fd = -EBADF;
        } else {
-               ret = CGROUP2_SUPER_MAGIC;
+               layout = CGROUP2_SUPER_MAGIC;
+               cgroup2_root_fd = ops->cgroup2_root_fd;
        }
 
-       path = must_make_path_relative(cgroup, file, NULL);
-       *value = readat_file(h->fd, path);
-       if (!*value)
-               ret = -1;
+       path = must_make_path_relative(cgroup, NULL);
+       ret = cgroup_walkup_to_root(cgroup2_root_fd, h->fd, path, file, value);
+       if (ret < 0)
+               return ret;
+       if (ret == 1) {
+               *value = strdup("");
+               if (!*value)
+                       return -ENOMEM;
+       }
 
-       return ret;
+       return layout;
 }
 
 static int cgfsng_get_memory_stats_fd(struct cgroup_ops *ops, const char 
*cgroup)
@@ -918,6 +925,11 @@
 
        ops->cgroup_layout = CGROUP_LAYOUT_UNIFIED;
        ops->unified = new;
+
+       ops->cgroup2_root_fd = open(DEFAULT_CGROUP_MOUNTPOINT, O_DIRECTORY | 
O_PATH | O_CLOEXEC);
+       if (ops->cgroup2_root_fd < 0)
+               return -errno;
+
        return CGROUP2_SUPER_MAGIC;
 }
 
@@ -939,12 +951,13 @@
 {
        __do_free struct cgroup_ops *cgfsng_ops = NULL;
 
-       cgfsng_ops = malloc(sizeof(struct cgroup_ops));
+       cgfsng_ops = zalloc(sizeof(struct cgroup_ops));
        if (!cgfsng_ops)
                return ret_set_errno(NULL, ENOMEM);
 
-       memset(cgfsng_ops, 0, sizeof(struct cgroup_ops));
        cgfsng_ops->cgroup_layout = CGROUP_LAYOUT_UNKNOWN;
+       cgfsng_ops->mntns_fd = -EBADF;
+       cgfsng_ops->cgroup2_root_fd = -EBADF;
 
        if (cg_init(cgfsng_ops))
                return NULL;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroups/cgroup.c 
new/lxcfs-4.0.3/src/cgroups/cgroup.c
--- old/lxcfs-4.0.1/src/cgroups/cgroup.c        2020-03-19 15:21:36.000000000 
+0100
+++ new/lxcfs-4.0.3/src/cgroups/cgroup.c        2020-04-17 22:15:36.000000000 
+0200
@@ -72,6 +72,9 @@
        if (ops->mntns_fd >= 0)
                close(ops->mntns_fd);
 
+       if (ops->cgroup2_root_fd >= 0)
+               close(ops->cgroup2_root_fd);
+
        free(ops->hierarchies);
 
        free(ops);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroups/cgroup.h 
new/lxcfs-4.0.3/src/cgroups/cgroup.h
--- old/lxcfs-4.0.1/src/cgroups/cgroup.h        2020-03-19 15:21:36.000000000 
+0100
+++ new/lxcfs-4.0.3/src/cgroups/cgroup.h        2020-04-17 22:15:36.000000000 
+0200
@@ -91,6 +91,12 @@
         */
        int mntns_fd;
 
+       /*
+        * A file descriptor to the root of the cgroup tree if we're on a
+        * cgroup2 only system.
+        */
+       int cgroup2_root_fd;
+
        /* string constant */
        const char *driver;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroups/cgroup2_devices.h 
new/lxcfs-4.0.3/src/cgroups/cgroup2_devices.h
--- old/lxcfs-4.0.1/src/cgroups/cgroup2_devices.h       2020-03-19 
15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/cgroups/cgroup2_devices.h       2020-04-17 
22:15:36.000000000 +0200
@@ -30,40 +30,15 @@
 #include <linux/filter.h>
 #endif
 
+#include "syscall_numbers.h"
+
 #if !HAVE_BPF
-#if !(defined __NR_bpf && __NR_bpf > 0)
-#if defined __NR_bpf
-#undef __NR_bpf
-#endif
-#if defined __i386__
-#define __NR_bpf 357
-#elif defined __x86_64__
-#define __NR_bpf 321
-#elif defined __aarch64__
-#define __NR_bpf 280
-#elif defined __arm__
-#define __NR_bpf 386
-#elif defined __sparc__
-#define __NR_bpf 349
-#elif defined __s390__
-#define __NR_bpf 351
-#elif defined __tilegx__
-#define __NR_bpf 280
-#else
-#warning "__NR_bpf not defined for your architecture"
-#endif
-#endif
 
 union bpf_attr;
 
 static inline int missing_bpf(int cmd, union bpf_attr *attr, size_t size)
 {
-#ifdef __NR_bpf
        return (int)syscall(__NR_bpf, cmd, attr, size);
-#else
-       errno = ENOSYS;
-       return -1;
-#endif
 }
 
 #define bpf missing_bpf
@@ -77,7 +52,7 @@
        size_t n_instructions;
 #ifdef HAVE_STRUCT_BPF_CGROUP_DEV_CTX
        struct bpf_insn *instructions;
-#endif
+#endif /* HAVE_STRUCT_BPF_CGROUP_DEV_CTX */
 
        char *attached_path;
        int attached_type;
@@ -102,7 +77,7 @@
                *prog = NULL;
        }
 }
-#else
+#else /* HAVE_STRUCT_BPF_CGROUP_DEV_CTX */
 static inline struct bpf_program *bpf_program_new(uint32_t prog_type)
 {
        errno = ENOSYS;
@@ -156,9 +131,8 @@
 {
 }
 
-#endif
+#endif /* HAVE_BPF */
 
-#define __do_bpf_program_free \
-       __attribute__((__cleanup__(__auto_bpf_program_free__)))
+define_cleanup_function(struct bpf_program *, bpf_program_free);
 
 #endif /* __LXC_CGROUP2_DEVICES_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroups/cgroup_utils.c 
new/lxcfs-4.0.3/src/cgroups/cgroup_utils.c
--- old/lxcfs-4.0.1/src/cgroups/cgroup_utils.c  2020-03-19 15:21:36.000000000 
+0100
+++ new/lxcfs-4.0.3/src/cgroups/cgroup_utils.c  2020-04-17 22:15:36.000000000 
+0200
@@ -724,3 +724,102 @@
 
        return true;
 }
+
+static bool same_file(int fd1, int fd2)
+{
+       struct stat st1, st2;
+
+       if (fstat(fd1, &st1) < 0 || fstat(fd2, &st2) < 0)
+               return false;
+
+       return (st1.st_dev == st2.st_dev) && (st1.st_ino == st2.st_ino);
+}
+
+/**
+ * cgroup_walkup_to_root() - Walk upwards to cgroup root to find valid value
+ *
+ * @cgroup2_root_fd:   File descriptor for the cgroup2 root mount point.
+ * @hierarchy_fd:      File descriptor for the hierarchy.
+ * @cgroup:            A cgroup directory relative to @hierarchy_fd.
+ * @file:              The file in @cgroup from which to read a value.
+ * @value:             Return argument to store value read from @file.
+ *
+ * This function tries to read a valid value from @file in @cgroup in
+ * @hierarchy_fd. If it is a legacy cgroup hierarchy and we fail to find a
+ * valid value we terminate early and report an error.
+ * The cgroup2 hierarchy however, has different semantics. In a few controller
+ * files it will show the value "max" or simply leave it completely empty
+ * thereby indicating that no limit has been set for this particular cgroup.
+ * However, that doesn't mean that there's no limit. A cgroup further up the
+ * hierarchy could have a limit set that also applies to the cgroup we are
+ * interested in. So for the unified cgroup hierarchy we need to keep walking
+ * towards the cgroup2 root cgroup and try to parse a valid value.
+ *
+ * Returns: 0 if a limit was found, 1 if no limit was set or "max" was set,
+ * -errno if an error occurred.
+ */
+int cgroup_walkup_to_root(int cgroup2_root_fd, int hierarchy_fd,
+                         const char *cgroup, const char *file, char **value)
+{
+       __do_close int dir_fd = -EBADF;
+       __do_free char *val = NULL;
+
+       /* Look in our current cgroup for a valid value. */
+       dir_fd = openat(hierarchy_fd, cgroup, O_DIRECTORY | O_PATH | O_CLOEXEC);
+       if (dir_fd < 0)
+               return -errno;
+
+       val = readat_file(dir_fd, file);
+       if (!is_empty_string(val) && strcmp(val, "max") != 0) {
+               *value = move_ptr(val);
+               return 0;
+       }
+
+       /*
+        * Legacy cgroup hierarchies should always show a valid value in the
+        * file of the cgroup. So no need to do this upwards walking crap.
+        */
+       if (cgroup2_root_fd < 0)
+               return -EINVAL;
+       else if (same_file(cgroup2_root_fd, dir_fd))
+               return 1;
+
+       free_disarm(val);
+       /*
+        * Set an arbitraty hard-coded limit to prevent us from ending
+        * up in an endless loop. There really shouldn't be any cgroup
+        * tree that is 1000 levels deep. That would be insane in
+        * principal and performance-wise.
+        */
+       for (int i = 0; i < 1000; i++) {
+               __do_close int inner_fd = -EBADF;
+               __do_free char *new_val = NULL;
+
+               inner_fd = move_fd(dir_fd);
+               dir_fd = openat(inner_fd, "..", O_DIRECTORY | O_PATH | 
O_CLOEXEC);
+               if (dir_fd < 0)
+                       return -errno;
+
+               /*
+                * We're at the root of the cgroup2 tree so stop walking
+                * upwards.
+                * Since we walked up the whole tree we haven't found an actual
+                * limit anywhere apparently.
+                *
+                * Note that we're not checking the root cgroup itself simply
+                * because a lot of the controllers don't expose files with
+                * limits to the root cgroup.
+                */
+               if (same_file(cgroup2_root_fd, dir_fd))
+                       return 1;
+
+               /* We found a valid value. Terminate walk. */
+               new_val = readat_file(dir_fd, file);
+               if (!is_empty_string(new_val) && strcmp(new_val, "max") != 0) {
+                       *value = move_ptr(new_val);
+                       return 0;
+               }
+       }
+
+       return log_error_errno(-ELOOP, ELOOP, "To many nested cgroups or 
invalid mount tree. Terminating walk");
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/cgroups/cgroup_utils.h 
new/lxcfs-4.0.3/src/cgroups/cgroup_utils.h
--- old/lxcfs-4.0.1/src/cgroups/cgroup_utils.h  2020-03-19 15:21:36.000000000 
+0100
+++ new/lxcfs-4.0.3/src/cgroups/cgroup_utils.h  2020-04-17 22:15:36.000000000 
+0200
@@ -95,6 +95,10 @@
        return openat(fd, path, O_DIRECTORY | O_RDONLY | O_CLOEXEC | 
O_NOFOLLOW);
 }
 
+extern int cgroup_walkup_to_root(int cgroup2_root_fd, int hierarchy_fd,
+                                const char *cgroup, const char *file,
+                                char **value);
+
 #define must_make_path_relative(__first__, ...)                                
\
        ({                                                                     \
                char *__ptr__;                                                 \
@@ -105,4 +109,9 @@
                __ptr__;                                                       \
        })
 
+static inline bool is_empty_string(const char *s)
+{
+       return !s || strcmp(s, "") == 0;
+}
+
 #endif /* __LXC_CGROUP_UTILS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/lxcfs.c new/lxcfs-4.0.3/src/lxcfs.c
--- old/lxcfs-4.0.1/src/lxcfs.c 2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/lxcfs.c 2020-04-17 22:15:36.000000000 +0200
@@ -1029,10 +1029,10 @@
        char buf[INTTYPE_TO_STRLEN(long)];
        int ret;
        struct flock fl = {
-               fl.l_type       = F_WRLCK,
-               fl.l_whence     = SEEK_SET,
-               fl.l_start      = 0,
-               fl.l_len        = 0,
+               .l_type         = F_WRLCK,
+               .l_whence       = SEEK_SET,
+               .l_start        = 0,
+               .l_len          = 0,
        };
 
        fd = open(pidfile, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | O_CLOEXEC);
@@ -1124,8 +1124,8 @@
                        } else if (strcmp(token, "nonempty") == 0) {
                                nonempty = true;
                        } else {
-                               free(v);
                                lxcfs_error("Warning: unexpected fuse option 
%s", v);
+                               free(v);
                                exit(EXIT_FAILURE);
                        }
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/memory_utils.h 
new/lxcfs-4.0.3/src/memory_utils.h
--- old/lxcfs-4.0.1/src/memory_utils.h  2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/memory_utils.h  2020-04-17 22:15:36.000000000 +0200
@@ -31,12 +31,12 @@
        }
 
 #define close_prot_errno_replace(fd, new_fd) \
-       if (fd >= 0) {                       \
-               int _e_ = errno;             \
-               close(fd);                   \
-               errno = _e_;                 \
-               fd = new_fd;                 \
-       }
+       if (fd >= 0) {                       \
+               int _e_ = errno;             \
+               close(fd);                   \
+               errno = _e_;                 \
+               fd = new_fd;                 \
+       }
 
 static inline void close_prot_errno_disarm_function(int *fd)
 {
@@ -50,10 +50,10 @@
 define_cleanup_function(DIR *, closedir);
 #define __do_closedir call_cleaner(closedir)
 
-#define free_disarm(ptr)       \
-       ({                     \
-               free(ptr);     \
-               move_ptr(ptr); \
+#define free_disarm(ptr)    \
+       ({                  \
+               free(ptr);  \
+               ptr = NULL; \
        })
 
 static inline void free_disarm_function(void *ptr)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/proc_fuse.c 
new/lxcfs-4.0.3/src/proc_fuse.c
--- old/lxcfs-4.0.1/src/proc_fuse.c     2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/proc_fuse.c     2020-04-17 22:15:36.000000000 +0200
@@ -203,19 +203,15 @@
 static uint64_t get_memlimit(const char *cgroup, bool swap)
 {
        __do_free char *memlimit_str = NULL;
-       uint64_t memlimit = -1;
-       char *ptr;
+       uint64_t memlimit = 0;
        int ret;
 
        if (swap)
                ret = cgroup_ops->get_memory_swap_max(cgroup_ops, cgroup, 
&memlimit_str);
        else
                ret = cgroup_ops->get_memory_max(cgroup_ops, cgroup, 
&memlimit_str);
-       if (ret > 0) {
-               memlimit = strtoull(memlimit_str, &ptr, 10);
-               if (ptr == memlimit_str)
-                       memlimit = -1;
-       }
+       if (ret > 0 && safe_uint64(memlimit_str, &memlimit, 10) < 0)
+               lxcfs_error("Failed to convert memlimit %s", memlimit_str);
 
        return memlimit;
 }
@@ -223,23 +219,20 @@
 static uint64_t get_min_memlimit(const char *cgroup, bool swap)
 {
        __do_free char *copy = NULL;
-       uint64_t memlimit = 0;
-       uint64_t retlimit;
+       uint64_t memlimit = 0, retlimit = 0;
 
        copy = strdup(cgroup);
        if (!copy)
                return log_error_errno(0, ENOMEM, "Failed to allocate memory");
 
        retlimit = get_memlimit(copy, swap);
-       if (retlimit == -1)
-               retlimit = 0;
 
        while (strcmp(copy, "/") != 0) {
                char *it = copy;
 
                it = dirname(it);
                memlimit = get_memlimit(it, swap);
-               if (memlimit != -1 && memlimit < retlimit)
+               if (memlimit > 0 && memlimit < retlimit)
                        retlimit = memlimit;
        };
 
@@ -296,14 +289,18 @@
        if (ret < 0)
                return 0;
 
-       memusage = strtoull(memusage_str, NULL, 10);
+       if (safe_uint64(memusage_str, &memusage, 10) < 0)
+               lxcfs_error("Failed to convert memusage %s", memusage_str);
 
        ret = cgroup_ops->get_memory_swap_max(cgroup_ops, cg, &memswlimit_str);
        if (ret >= 0)
                ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cg, 
&memswusage_str);
        if (ret >= 0) {
                memswlimit = get_min_memlimit(cg, true);
-               memswusage = strtoull(memswusage_str, NULL, 10);
+
+               if (safe_uint64(memswusage_str, &memswusage, 10) < 0)
+                       lxcfs_error("Failed to convert memswusage %s", 
memswusage_str);
+
                swap_total = (memswlimit - memlimit) / 1024;
                swap_free = (memswusage - memusage) / 1024;
        }
@@ -524,7 +521,8 @@
 }
 #endif
 
-/* This function retrieves the busy time of a group of tasks by looking at
+/*
+ * This function retrieves the busy time of a group of tasks by looking at
  * cpuacct.usage. Unfortunately, this only makes sense when the container has
  * been given it's own cpuacct cgroup. If not, this function will take the busy
  * time of all other taks that do not actually belong to the container into
@@ -545,10 +543,13 @@
        if (!cgroup)
                return 0;
        prune_init_slice(cgroup);
+
        if (!cgroup_ops->get(cgroup_ops, "cpuacct", cgroup, "cpuacct.usage", 
&usage_str))
                return 0;
 
-       usage = strtoull(usage_str, NULL, 10);
+       if (safe_uint64(usage_str, &usage, 10) < 0)
+               lxcfs_error("Failed to convert usage %s", usage_str);
+
        return ((double)usage / 1000000000);
 }
 
@@ -558,38 +559,21 @@
        __do_fclose FILE *f = NULL;
        int ret;
        uint64_t starttime;
-       /* strlen("/proc/") = 6
-        * +
-        * LXCFS_NUMSTRLEN64
-        * +
-        * strlen("/stat") = 5
-        * +
-        * \0 = 1
-        * */
-#define __PROC_PID_STAT_LEN (6 + LXCFS_NUMSTRLEN64 + 5 + 1)
-       char path[__PROC_PID_STAT_LEN];
+       char path[STRLITERALLEN("/proc/") + LXCFS_NUMSTRLEN64 +
+                 STRLITERALLEN("/stat") + 1];
        pid_t qpid;
 
        qpid = lookup_initpid_in_store(pid);
-       if (qpid <= 0) {
-               /* Caller can check for EINVAL on 0. */
-               errno = EINVAL;
-               return 0;
-       }
+       if (qpid <= 0)
+               return ret_errno(EINVAL);
 
-       ret = snprintf(path, __PROC_PID_STAT_LEN, "/proc/%d/stat", qpid);
-       if (ret < 0 || ret >= __PROC_PID_STAT_LEN) {
-               /* Caller can check for EINVAL on 0. */
-               errno = EINVAL;
-               return 0;
-       }
+       ret = snprintf(path, sizeof(path), "/proc/%d/stat", qpid);
+       if (ret < 0 || (size_t)ret >= sizeof(path))
+               return ret_errno(EINVAL);
 
        f = fopen_cached(path, "re", &fopen_cache);
-       if (!f) {
-               /* Caller can check for EINVAL on 0. */
-               errno = EINVAL;
-               return 0;
-       }
+       if (!f)
+               return ret_errno(EINVAL);
 
        /* Note that the *scanf() argument supression requires that length
         * modifiers such as "l" are omitted. Otherwise some compilers will yell
@@ -620,7 +604,7 @@
                        "%" PRIu64, /* (22) starttime   %llu */
                     &starttime);
        if (ret != 1)
-               return ret_set_errno(0, EINVAL);
+               return ret_errno(EINVAL);
 
        return ret_set_errno(starttime, 0);
 }
@@ -632,11 +616,11 @@
        double res = 0;
 
        clockticks = get_reaper_start_time(pid);
-       if (clockticks == 0 && errno == EINVAL)
+       if (clockticks <= 0)
                return log_debug(0, "Failed to retrieve start time of pid %d", 
pid);
 
        ret = sysconf(_SC_CLK_TCK);
-       if (ret < 0 && errno == EINVAL)
+       if (ret < 0)
                return log_debug(0, "Failed to determine number of clock ticks 
in a second");
 
        ticks_per_sec = (uint64_t)ret;
@@ -649,7 +633,8 @@
        uint64_t uptime_ms;
        double procstart, procage;
 
-       /* We need to substract the time the process has started since system
+       /*
+        * We need to substract the time the process has started since system
         * boot minus the time when the system has started to get the actual
         * reaper age.
         */
@@ -663,11 +648,6 @@
                if (ret < 0)
                        return 0;
 
-               /* We could make this more precise here by using the tv_nsec
-                * field in the timespec struct and convert it to milliseconds
-                * and then create a double for the seconds and milliseconds but
-                * that seems more work than it is worth.
-                */
                uptime_ms = (spec.tv_sec * 1000) + (spec.tv_nsec * 1e-6);
                procage = (uptime_ms - (procstart * 1000)) / 1000;
        }
@@ -721,7 +701,7 @@
 
        total_len = snprintf(d->buf, d->buflen, "%.2lf %.2lf\n", reaperage, 
idletime);
        if (total_len < 0 || total_len >= d->buflen)
-               return log_error(0, "Failed to write to cache");
+               return read_file_fuse("/proc/uptime", buf, size, d);
 
        d->size = (int)total_len;
        d->cached = 1;
@@ -730,6 +710,7 @@
                total_len = size;
 
        memcpy(buf, d->buf, total_len);
+
        return total_len;
 }
 
@@ -1038,7 +1019,7 @@
        struct lxcfs_opts *opts = (struct lxcfs_opts 
*)fuse_get_context()->private_data;
        struct file_info *d = INTTYPE_TO_PTR(fi->fh);
        uint64_t memlimit = 0, memusage = 0, memswlimit = 0, memswusage = 0,
-                hosttotal = 0;
+                hosttotal = 0, swtotal = 0;
        struct memory_stat mstat = {};
        size_t linelen = 0, total_len = 0;
        char *cache = d->buf;
@@ -1075,10 +1056,10 @@
 
        ret = cgroup_ops->get_memory_current(cgroup_ops, cgroup, &memusage_str);
        if (ret < 0)
-               return 0;
+               return read_file_fuse("/proc/meminfo", buf, size, d);
 
        if (!cgroup_parse_memory_stat(cgroup, &mstat))
-               return 0;
+               return read_file_fuse("/proc/meminfo", buf, size, d);
 
        /*
         * Following values are allowed to fail, because swapaccount might be
@@ -1089,18 +1070,22 @@
                ret = cgroup_ops->get_memory_swap_current(cgroup_ops, cgroup, 
&memswusage_str);
        if (ret >= 0) {
                memswlimit = get_min_memlimit(cgroup, true);
-               memswusage = strtoull(memswusage_str, NULL, 10);
                memswlimit = memswlimit / 1024;
+
+               if (safe_uint64(memswusage_str, &memswusage, 10) < 0)
+                       lxcfs_error("Failed to convert memswusage %s", 
memswusage_str);
                memswusage = memswusage / 1024;
+               swtotal = memswlimit;
        }
 
-       memusage = strtoull(memusage_str, NULL, 10);
+       if (safe_uint64(memusage_str, &memusage, 10) < 0)
+               lxcfs_error("Failed to convert memusage %s", memusage_str);
        memlimit /= 1024;
        memusage /= 1024;
 
        f = fopen_cached("/proc/meminfo", "re", &fopen_cache);
        if (!f)
-               return 0;
+               return read_file_fuse("/proc/meminfo", buf, size, d);
 
        while (getline(&line, &linelen, f) != -1) {
                ssize_t l;
@@ -1109,6 +1094,9 @@
                memset(lbuf, 0, 100);
                if (startswith(line, "MemTotal:")) {
                        sscanf(line+sizeof("MemTotal:")-1, "%" PRIu64, 
&hosttotal);
+                       if (memlimit == 0)
+                               memlimit = hosttotal;
+
                        if (hosttotal < memlimit)
                                memlimit = hosttotal;
                        snprintf(lbuf, 100, "MemTotal:       %8" PRIu64 " 
kB\n", memlimit);
@@ -1119,24 +1107,29 @@
                } else if (startswith(line, "MemAvailable:")) {
                        snprintf(lbuf, 100, "MemAvailable:   %8" PRIu64 " 
kB\n", memlimit - memusage + mstat.total_cache / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "SwapTotal:") && memswlimit > 0 &&
-                          opts && opts->swap_off == false) {
-                       memswlimit -= memlimit;
-                       snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " 
kB\n", memswlimit);
+               } else if (startswith(line, "SwapTotal:") && memswlimit > 0 && 
opts && opts->swap_off == false) {
+                       uint64_t hostswtotal = 0;
+
+                       sscanf(line + STRLITERALLEN("SwapTotal:"), "%" PRIu64, 
&hostswtotal);
+
+                       /* Don't advertise more SWAP than the total memory 
allowed. */
+                       if (hostswtotal < swtotal)
+                               swtotal = hostswtotal;
+
+                       snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " 
kB\n", swtotal);
                        printme = lbuf;
                } else if (startswith(line, "SwapTotal:") && opts && 
opts->swap_off == true) {
                        snprintf(lbuf, 100, "SwapTotal:      %8" PRIu64 " 
kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "SwapFree:") && memswlimit > 0 &&
-                          memswusage > 0 && opts && opts->swap_off == false) {
-                       uint64_t swaptotal = memswlimit,
-                                swapusage = memusage > memswusage
-                                                ? 0
-                                                : memswusage - memusage,
-                                swapfree = swapusage < swaptotal
-                                               ? swaptotal - swapusage
-                                               : 0;
-                       snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " 
kB\n", swapfree);
+                          opts && opts->swap_off == false) {
+                       uint64_t swfree = 0;
+                       uint64_t swusage = 0;
+
+                       swusage = memswusage - memusage;
+                       swfree = swtotal - swusage;
+
+                       snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " 
kB\n", swfree);
                        printme = lbuf;
                } else if (startswith(line, "SwapFree:") && opts && 
opts->swap_off == true) {
                        snprintf(lbuf, 100, "SwapFree:       %8" PRIu64 " 
kB\n", (uint64_t)0);
@@ -1166,61 +1159,61 @@
                                  mstat.total_inactive_file) /
                                     1024);
                        printme = lbuf;
-               } else if (startswith(line, "Active(anon)")) {
+               } else if (startswith(line, "Active(anon):")) {
                        snprintf(lbuf, 100, "Active(anon):   %8" PRIu64 " kB\n",
                                 mstat.total_active_anon / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "Inactive(anon)")) {
+               } else if (startswith(line, "Inactive(anon):")) {
                        snprintf(lbuf, 100, "Inactive(anon): %8" PRIu64 " kB\n",
                                 mstat.total_inactive_anon / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "Active(file)")) {
+               } else if (startswith(line, "Active(file):")) {
                        snprintf(lbuf, 100, "Active(file):   %8" PRIu64 " kB\n",
                                 mstat.total_active_file / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "Inactive(file)")) {
+               } else if (startswith(line, "Inactive(file):")) {
                        snprintf(lbuf, 100, "Inactive(file): %8" PRIu64 " kB\n",
                                 mstat.total_inactive_file / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "Unevictable")) {
+               } else if (startswith(line, "Unevictable:")) {
                        snprintf(lbuf, 100, "Unevictable:    %8" PRIu64 " kB\n",
                                 mstat.total_unevictable / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "Dirty")) {
+               } else if (startswith(line, "Dirty:")) {
                        snprintf(lbuf, 100, "Dirty:          %8" PRIu64 " kB\n",
                                 mstat.total_dirty / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "Writeback")) {
+               } else if (startswith(line, "Writeback:")) {
                        snprintf(lbuf, 100, "Writeback:      %8" PRIu64 " kB\n",
                                 mstat.total_writeback / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "AnonPages")) {
+               } else if (startswith(line, "AnonPages:")) {
                        snprintf(lbuf, 100, "AnonPages:      %8" PRIu64 " kB\n",
                                 (mstat.total_active_anon +
                                  mstat.total_inactive_anon - 
mstat.total_shmem) /
                                     1024);
                        printme = lbuf;
-               } else if (startswith(line, "Mapped")) {
+               } else if (startswith(line, "Mapped:")) {
                        snprintf(lbuf, 100, "Mapped:         %8" PRIu64 " kB\n",
                                 mstat.total_mapped_file / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "SReclaimable")) {
+               } else if (startswith(line, "SReclaimable:")) {
                        snprintf(lbuf, 100, "SReclaimable:   %8" PRIu64 " 
kB\n", (uint64_t)0);
                        printme = lbuf;
-               } else if (startswith(line, "SUnreclaim")) {
+               } else if (startswith(line, "SUnreclaim:")) {
                        snprintf(lbuf, 100, "SUnreclaim:     %8" PRIu64 " 
kB\n", (uint64_t)0);
                        printme = lbuf;
                } else if (startswith(line, "Shmem:")) {
                        snprintf(lbuf, 100, "Shmem:          %8" PRIu64 " kB\n",
                                 mstat.total_shmem / 1024);
                        printme = lbuf;
-               } else if (startswith(line, "ShmemHugePages")) {
+               } else if (startswith(line, "ShmemHugePages:")) {
                        snprintf(lbuf, 100, "ShmemHugePages: %8" PRIu64 " 
kB\n", (uint64_t)0);
                        printme = lbuf;
-               } else if (startswith(line, "ShmemPmdMapped")) {
+               } else if (startswith(line, "ShmemPmdMapped:")) {
                        snprintf(lbuf, 100, "ShmemPmdMapped: %8" PRIu64 " 
kB\n", (uint64_t)0);
                        printme = lbuf;
-               } else if (startswith(line, "AnonHugePages")) {
+               } else if (startswith(line, "AnonHugePages:")) {
                        snprintf(lbuf, 100, "AnonHugePages:  %8" PRIu64 " kB\n",
                                 mstat.total_rss_huge / 1024);
                        printme = lbuf;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/syscall_numbers.h 
new/lxcfs-4.0.3/src/syscall_numbers.h
--- old/lxcfs-4.0.1/src/syscall_numbers.h       1970-01-01 01:00:00.000000000 
+0100
+++ new/lxcfs-4.0.3/src/syscall_numbers.h       2020-04-17 22:15:36.000000000 
+0200
@@ -0,0 +1,118 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+#ifndef __LXCFS_SYSCALL_NUMBERS_H
+#define __LXCFS_SYSCALL_NUMBERS_H
+
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE 1
+#endif
+#include <asm/unistd.h>
+#include <errno.h>
+#include <sched.h>
+#include <stdint.h>
+#include <sys/syscall.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#ifndef __NR_pivot_root
+       #if defined __i386__
+               #define __NR_pivot_root 217
+       #elif defined __x86_64__
+               #define __NR_pivot_root 155
+       #elif defined __arm__
+               #define __NR_pivot_root 218
+       #elif defined __aarch64__
+               #define __NR_pivot_root 218
+       #elif defined __s390__
+               #define __NR_pivot_root 217
+       #elif defined __powerpc__
+               #define __NR_pivot_root 203
+       #elif defined __sparc__
+               #define __NR_pivot_root 146
+       #elif defined __ia64__
+               #define __NR_pivot_root 183
+       #elif defined _MIPS_SIM
+               #if _MIPS_SIM == _MIPS_SIM_ABI32        /* o32 */
+                       #define __NR_pivot_root 4216
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_NABI32       /* n32 */
+                       #define __NR_pivot_root 6151
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_ABI64        /* n64 */
+                       #define __NR_pivot_root 5151
+               #endif
+       #else
+               #define -1
+               #warning "__NR_pivot_root not defined for your architecture"
+       #endif
+#endif
+
+#ifndef __NR_bpf
+       #if defined __i386__
+               #define __NR_bpf 357
+       #elif defined __x86_64__
+               #define __NR_bpf 321
+       #elif defined __arm__
+               #define __NR_bpf 386
+       #elif defined __aarch64__
+               #define __NR_bpf 386
+       #elif defined __s390__
+               #define __NR_bpf 351
+       #elif defined __powerpc__
+               #define __NR_bpf 361
+       #elif defined __sparc__
+               #define __NR_bpf 349
+       #elif defined __ia64__
+               #define __NR_bpf 317
+       #elif defined _MIPS_SIM
+               #if _MIPS_SIM == _MIPS_SIM_ABI32        /* o32 */
+                       #define __NR_bpf 4355
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_NABI32       /* n32 */
+                       #define __NR_bpf 6319
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_ABI64        /* n64 */
+                       #define __NR_bpf 5315
+               #endif
+       #else
+               #define -1
+               #warning "__NR_bpf not defined for your architecture"
+       #endif
+#endif
+
+#ifndef __NR_pidfd_send_signal
+       #if defined __alpha__
+               #define __NR_pidfd_send_signal 534
+       #elif defined _MIPS_SIM
+               #if _MIPS_SIM == _MIPS_SIM_ABI32        /* o32 */
+                       #define __NR_pidfd_send_signal 4424
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_NABI32       /* n32 */
+                       #define __NR_pidfd_send_signal 6424
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_ABI64        /* n64 */
+                       #define __NR_pidfd_send_signal 5424
+               #endif
+       #else
+               #define __NR_pidfd_send_signal 424
+       #endif
+#endif
+
+#ifndef __NR_pidfd_open
+       #if defined __alpha__
+               #define __NR_pidfd_open 544
+       #elif defined _MIPS_SIM
+               #if _MIPS_SIM == _MIPS_SIM_ABI32        /* o32 */
+                       #define __NR_pidfd_open 4434
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_NABI32       /* n32 */
+                       #define __NR_pidfd_open 6434
+               #endif
+               #if _MIPS_SIM == _MIPS_SIM_ABI64        /* n64 */
+                       #define __NR_pidfd_open 5434
+               #endif
+       #else
+               #define __NR_pidfd_open 434
+       #endif
+#endif
+
+#endif /* __LXCFS_SYSCALL_NUMBERS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/utils.c new/lxcfs-4.0.3/src/utils.c
--- old/lxcfs-4.0.1/src/utils.c 2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/utils.c 2020-04-17 22:15:36.000000000 +0200
@@ -10,13 +10,13 @@
 
 #define _FILE_OFFSET_BITS 64
 
+#include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <fuse.h>
 #include <inttypes.h>
 #include <sched.h>
 #include <stdarg.h>
-#include <stdio.h>
 #include <stdbool.h>
 #include <stdint.h>
 #include <stdio.h>
@@ -212,37 +212,34 @@
 
 bool recv_creds(int sock, struct ucred *cred, char *v)
 {
-       struct msghdr msg = { 0 };
+       struct msghdr msg = {};
        struct iovec iov;
        struct cmsghdr *cmsg;
-       char cmsgbuf[CMSG_SPACE(sizeof(*cred))];
-       char buf[1];
-       int ret;
+       ssize_t ret;
+       char cmsgbuf[CMSG_SPACE(sizeof(*cred))] = {};
+       char buf = '1';
        int optval = 1;
 
-       *v = '1';
-
-       cred->pid = -1;
-       cred->uid = -1;
-       cred->gid = -1;
-
-       if (setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &optval, sizeof(optval)) 
== -1)
-               return log_error(false, "Failed to set passcred: %s\n", 
strerror(errno));
-
-       buf[0] = '1';
-       if (write(sock, buf, 1) != 1)
-               return log_error(false, "Failed to start write on scm fd: 
%s\n", strerror(errno));
-
        msg.msg_name = NULL;
        msg.msg_namelen = 0;
        msg.msg_control = cmsgbuf;
        msg.msg_controllen = sizeof(cmsgbuf);
 
-       iov.iov_base = buf;
+       iov.iov_base = &buf;
        iov.iov_len = sizeof(buf);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;
 
+       *v = buf;
+
+       ret = setsockopt(sock, SOL_SOCKET, SO_PASSCRED, &optval, 
sizeof(optval));
+       if (ret < 0)
+               return log_error(false, "Failed to set passcred: %s\n", 
strerror(errno));
+
+       ret = write_nointr(sock, &buf, sizeof(buf));
+       if (ret != sizeof(buf))
+               return log_error(false, "Failed to start write on scm fd: 
%s\n", strerror(errno));
+
        if (!wait_for_sock(sock, 2))
                return log_error(false, "Timed out waiting for scm_cred: %s\n", 
strerror(errno));
 
@@ -252,12 +249,12 @@
 
        cmsg = CMSG_FIRSTHDR(&msg);
 
-       if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)) &&
-                       cmsg->cmsg_level == SOL_SOCKET &&
-                       cmsg->cmsg_type == SCM_CREDENTIALS) {
+       if (cmsg && cmsg->cmsg_len == CMSG_LEN(sizeof(*cred)) &&
+           cmsg->cmsg_level == SOL_SOCKET &&
+           cmsg->cmsg_type == SCM_CREDENTIALS) {
                memcpy(cred, CMSG_DATA(cmsg), sizeof(*cred));
        }
-       *v = buf[0];
+       *v = buf;
 
        return true;
 }
@@ -520,3 +517,26 @@
 
        return ret;
 }
+
+int safe_uint64(const char *numstr, uint64_t *converted, int base)
+{
+       char *err = NULL;
+       uint64_t u;
+
+       while (isspace(*numstr))
+               numstr++;
+
+       if (*numstr == '-')
+               return -EINVAL;
+
+       errno = 0;
+       u = strtoull(numstr, &err, base);
+       if (errno == ERANGE && u == UINT64_MAX)
+               return -ERANGE;
+
+       if (err == numstr || *err != '\0')
+               return -EINVAL;
+
+       *converted = u;
+       return 0;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/src/utils.h new/lxcfs-4.0.3/src/utils.h
--- old/lxcfs-4.0.1/src/utils.h 2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/src/utils.h 2020-04-17 22:15:36.000000000 +0200
@@ -24,6 +24,7 @@
 
 #include "config.h"
 #include "macro.h"
+#include "syscall_numbers.h"
 
 /* Reserve buffer size to account for file size changes. */
 #define BUF_RESERVE_SIZE 512
@@ -51,11 +52,7 @@
 #ifndef HAVE_PIDFD_OPEN
 static inline int pidfd_open(pid_t pid, unsigned int flags)
 {
-#ifdef __NR_pidfd_open
        return syscall(__NR_pidfd_open, pid, flags);
-#else
-       return ret_errno(ENOSYS);
-#endif
 }
 #endif
 
@@ -63,11 +60,7 @@
 static inline int pidfd_send_signal(int pidfd, int sig, siginfo_t *info,
                                    unsigned int flags)
 {
-#ifdef __NR_pidfd_send_signal
        return syscall(__NR_pidfd_send_signal, pidfd, sig, info, flags);
-#else
-       return ret_errno(ENOSYS);
-#endif
 }
 #endif
 
@@ -75,5 +68,6 @@
                          void **caller_freed_buffer);
 extern FILE *fdopen_cached(int fd, const char *mode, void 
**caller_freed_buffer);
 extern ssize_t write_nointr(int fd, const void *buf, size_t count);
+extern int safe_uint64(const char *numstr, uint64_t *converted, int base);
 
 #endif /* __LXCFS_UTILS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/tests/test_readdir 
new/lxcfs-4.0.3/tests/test_readdir
--- old/lxcfs-4.0.1/tests/test_readdir  2020-03-19 15:21:36.000000000 +0100
+++ new/lxcfs-4.0.3/tests/test_readdir  2020-04-17 22:15:36.000000000 +0200
@@ -20,10 +20,12 @@
     exit 1
 fi
 
-echo "==> Checking for cpuset cgroups"
-[ ! -d /sys/fs/cgroup/cpuset ] && exit 0
-
 TESTCASE="Stress readdir"
-for i in `seq 1 1000`;do ls -al "${LXCFSDIR}/cgroup/cpuset" >/dev/null; done
+echo "==> Checking for cpuset cgroups"
+if [ -d /sys/fs/cgroup/cpuset ]; then
+   for i in `seq 1 1000`;do ls -al "${LXCFSDIR}/cgroup/cpuset" >/dev/null; done
+else
+   echo "==> Skipping $TESTCASE"
+fi
 
 PASS=1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/lxcfs-4.0.1/tests/test_reload.sh 
new/lxcfs-4.0.3/tests/test_reload.sh
--- old/lxcfs-4.0.1/tests/test_reload.sh        2020-03-19 15:21:36.000000000 
+0100
+++ new/lxcfs-4.0.3/tests/test_reload.sh        2020-04-17 22:15:36.000000000 
+0200
@@ -13,7 +13,7 @@
 testdir=`mktemp -t -d libs.XXX`
 installdir=`mktemp -t -d libs.XXX`
 pidfile=$(mktemp)
-libdir=${installdir}/usr/lib/lxcfs
+libdir=${installdir}/$(grep ^LIBDIR Makefile | awk '{print $NF}')
 bindir=${installdir}/usr/bin
 lxcfspid=-1
 FAILED=1


Reply via email to