]> git.proxmox.com Git - mirror_lxcfs.git/commitdiff
lxcfs: handle NULL path in lxcfs_releasedir/lxcfs_release
authorMatthew Ife <matthewi@mustardsystems.com>
Wed, 11 Jan 2023 14:30:06 +0000 (14:30 +0000)
committerMatthew Ife <matthewi@mustardsystems.com>
Thu, 12 Jan 2023 16:10:39 +0000 (16:10 +0000)
Implement a file_info_type function.
Create a series of defines for the file type

Inspect the file type for each file handler and perform the relevant
release code to free any memory.

If the type cannot be determined, print an error and return -EINVAL.

This should also be slightly faster than a strcmp() but its not likely
that measurable.

This code could be used elsewhere in the process to reduce the strcmp
requirements, but for now just handle the release/releasedir case.

This fixes SEGV in lxcfs_relase/releasedir when path=NULL but invoked a
strcmp().

Signed-off-by: Matthew Ife <matthewi@mustardsystems.com>
src/bindings.h
src/lxcfs.c

index 1624784e2870e3f2527afdfd53b5c0bc7a169c52..8d9d6eb1ccb5eea8bc89380b7056e527c03a9749 100644 (file)
@@ -30,6 +30,8 @@
 /* Maximum number for 64 bit integer is a string with 21 digits: 2^64 - 1 = 21 */
 #define LXCFS_NUMSTRLEN64 21
 
+/* The definitions here are well-ordered. New values should go directly
+ * above LXC_TYPE_MAX only. */
 enum lxcfs_virt_t {
        LXC_TYPE_CGDIR,
        LXC_TYPE_CGFILE,
@@ -67,8 +69,15 @@ enum lxcfs_virt_t {
 
        LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE,
 #define LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE_PATH "/sys/devices/system/cpu/online"
+       LXC_TYPE_MAX,
 };
 
+/* Macros below used to check the class from the file types above */
+#define LXCFS_TYPE_CGROUP(type) (type >= LXC_TYPE_CGDIR && type <= LXC_TYPE_CGFILE)
+#define LXCFS_TYPE_PROC(type) (type >= LXC_TYPE_PROC_MEMINFO && type <= LXC_TYPE_PROC_SLABINFO)
+#define LXCFS_TYPE_SYS(type) (type >= LXC_TYPE_SYS && type <= LXC_TYPE_SYS_DEVICES_SYSTEM_CPU_ONLINE)
+#define LXCFS_TYPE_OK(type) (type >= LXC_TYPE_CGDIR && type < LXC_TYPE_MAX)
+
 struct file_info {
        char *controller;
        char *cgroup;
index c6f83a84c550aaa4176b6c8825a626907f8704ca..92ed991217c1dc069fa9e5f7b59734faa06f7449 100644 (file)
@@ -8,6 +8,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
+#include <inttypes.h>
 #include <libgen.h>
 #include <pthread.h>
 #include <sched.h>
@@ -65,6 +66,22 @@ static inline void users_unlock(void)
        unlock_mutex(&user_count_mutex);
 }
 
+/* Returns file info type of custom type declaration carried
+ * in fuse_file_info */
+static inline enum lxcfs_virt_t file_info_type(struct fuse_file_info *fi)
+{
+       struct file_info *f;
+
+       f = INTTYPE_TO_PTR(fi->fh);
+       if (!f)
+               return -1;
+
+       if (!LXCFS_TYPE_OK(f->type))
+               return -1;
+
+       return f->type;
+}
+
 static pthread_t loadavg_pid = 0;
 
 /* Returns zero on success */
@@ -770,27 +787,34 @@ static int lxcfs_access(const char *path, int mode)
 static int lxcfs_releasedir(const char *path, struct fuse_file_info *fi)
 {
        int ret;
+       enum lxcfs_virt_t type;
 
-       if (strcmp(path, "/") == 0)
-               return 0;
+       type = file_info_type(fi);
 
-       if (strncmp(path, "/cgroup", 7) == 0) {
+       if (LXCFS_TYPE_CGROUP(type)) {
                up_users();
                ret = do_cg_releasedir(path, fi);
                down_users();
                return ret;
        }
 
-       if (strcmp(path, "/proc") == 0)
-               return 0;
-
-       if (strncmp(path, "/sys", 4) == 0) {
+       if (LXCFS_TYPE_SYS(type)) {
                up_users();
                ret = do_sys_releasedir(path, fi);
                down_users();
                return ret;
        }
 
+       if (path) {
+               if (strcmp(path, "/") == 0)
+                       return 0;
+               if (strcmp(path, "/proc") == 0)
+                       return 0;
+       }
+
+       lxcfs_error("unknown file type: path=%s, type=%d, fi->fh=%" PRIu64,
+                       path, type, fi->fh);
+
        return -EINVAL;
 }
 
@@ -895,28 +919,34 @@ static int lxcfs_flush(const char *path, struct fuse_file_info *fi)
 static int lxcfs_release(const char *path, struct fuse_file_info *fi)
 {
        int ret;
+       enum lxcfs_virt_t type;
 
-       if (strncmp(path, "/cgroup", 7) == 0) {
+       type = file_info_type(fi);
+
+       if (LXCFS_TYPE_CGROUP(type)) {
                up_users();
                ret = do_cg_release(path, fi);
                down_users();
                return ret;
        }
 
-       if (strncmp(path, "/proc", 5) == 0) {
+       if (LXCFS_TYPE_PROC(type)) {
                up_users();
                ret = do_proc_release(path, fi);
                down_users();
                return ret;
        }
 
-       if (strncmp(path, "/sys", 4) == 0) {
+       if (LXCFS_TYPE_SYS(type)) {
                up_users();
                ret = do_sys_release(path, fi);
                down_users();
                return ret;
        }
 
+       lxcfs_error("unknown file type: path=%s, type=%d, fi->fh=%" PRIu64,
+                       path, type, fi->fh);
+
        return -EINVAL;
 }