jail: cgroups: replace wrongly used assert()
[project/procd.git] / jail / fs.c
index 4cc273eea973386a7cea2091928295ab0d1c79af..f70a751fa1a2813bd905a89bedeba70f332b28d0 100644 (file)
--- a/jail/fs.c
+++ b/jail/fs.c
@@ -32,6 +32,7 @@
 #include <libubox/avl-cmp.h>
 #include <libubox/blobmsg.h>
 #include <libubox/list.h>
+#include <libubox/utils.h>
 
 #include "elf.h"
 #include "fs.h"
@@ -54,31 +55,6 @@ struct mount {
 
 struct avl_tree mounts;
 
-int mkdir_p(char *dir, mode_t mask)
-{
-       char *l = strrchr(dir, '/');
-       int ret;
-
-       if (!l)
-               return 0;
-
-       *l = '\0';
-
-       if (mkdir_p(dir, mask))
-               return -1;
-
-       *l = '/';
-
-       ret = mkdir(dir, mask);
-       if (ret && errno == EEXIST)
-               return 0;
-
-       if (ret)
-               ERROR("mkdir(%s, %d) failed: %m\n", dir, mask);
-
-       return ret;
-}
-
 static int do_mount(const char *root, const char *orig_source, const char *target, const char *filesystemtype,
                    unsigned long orig_mountflags, unsigned long propflags, const char *optstr, int error, bool inner)
 {
@@ -111,10 +87,10 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
                                return error;
                } else {
                        /* mount-bind 0-sized file having mode 000 */
-                       if (mount(UJAIL_NOAFILE, new, NULL, MS_BIND, NULL))
+                       if (mount(UJAIL_NOAFILE, new, "bind", MS_BIND, NULL))
                                return error;
 
-                       if (mount(UJAIL_NOAFILE, new, NULL, MS_REMOUNT | MS_BIND | MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, NULL))
+                       if (mount(UJAIL_NOAFILE, new, "bind", MS_REMOUNT | MS_BIND | MS_RDONLY | MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_NOATIME, NULL))
                                return error;
                }
 
@@ -137,7 +113,7 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
        }
 
        if (is_bind) {
-               if (mount(source?:new, new, filesystemtype, MS_BIND | (mountflags & MS_REC), optstr)) {
+               if (mount(source?:new, new, filesystemtype?:"bind", MS_BIND | (mountflags & MS_REC), optstr)) {
                        if (error)
                                ERROR("failed to mount -B %s %s: %m\n", source, new);
 
@@ -149,7 +125,8 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
                mountflags |= MS_REMOUNT;
        }
 
-       if (mount(source?:(is_bind?new:NULL), new, filesystemtype, mountflags, optstr)) {
+       const char *hack_fstype = ((!filesystemtype || strcmp(filesystemtype, "cgroup"))?filesystemtype:"cgroup2");
+       if (mount(source?:(is_bind?new:NULL), new, hack_fstype?:"none", mountflags, optstr)) {
                if (error)
                        ERROR("failed to mount %s %s: %m\n", source, new);
 
@@ -162,7 +139,7 @@ static int do_mount(const char *root, const char *orig_source, const char *targe
        DEBUG("mount %s%s %s (%s)\n", (mountflags & MS_BIND)?"-B ":"", source, new,
              (mountflags & MS_RDONLY)?"ro":"rw");
 
-       if (propflags && mount(NULL, new, NULL, propflags, NULL)) {
+       if (propflags && mount("none", new, "none", propflags, NULL)) {
                if (error)
                        ERROR("failed to mount --make-... %s \n", new);
 
@@ -189,7 +166,9 @@ static int _add_mount(const char *source, const char *target, const char *filesy
 
        struct mount *m;
        m = calloc(1, sizeof(struct mount));
-       assert(m != NULL);
+       if (!m)
+               return ENOMEM;
+
        m->avl.key = m->target = strdup(target);
        if (source) {
                if (source != (void*)(-1))
@@ -270,7 +249,7 @@ static int parseOCImountopts(struct blob_attr *msg, unsigned long *mount_flags,
        char *tmp;
        struct list_head fsopts = LIST_HEAD_INIT(fsopts);
        size_t len = 0;
-       struct mount_opt *opt;
+       struct mount_opt *opt, *tmpopt;
 
        blobmsg_for_each_attr(cur, msg, rem) {
                tmp = blobmsg_get_string(cur);
@@ -388,9 +367,12 @@ static int parseOCImountopts(struct blob_attr *msg, unsigned long *mount_flags,
 
                        strcat(*mount_data, opt->optstr);
                        ++len;
-               };
+               }
 
-               list_del(&fsopts);
+               list_for_each_entry_safe(opt, tmpopt, &fsopts, list) {
+                       list_del(&opt->list);
+                       free(opt);
+               }
        }
 
        DEBUG("mount flags(%08lx) propagation(%08lx) fsopts(\"%s\")\n", mf, pf, *mount_data?:"");
@@ -456,6 +438,19 @@ int mount_all(const char *jailroot) {
        return 0;
 }
 
+void mount_free(void) {
+       struct mount *m, *tmp;
+
+       avl_remove_all_elements(&mounts, m, avl, tmp) {
+               if (m->source != (void*)(-1))
+                       free((void*)m->source);
+               free((void*)m->target);
+               free((void*)m->filesystemtype);
+               free((void*)m->optstr);
+               free(m);
+       }
+}
+
 void mount_list_init(void) {
        avl_init(&mounts, avl_strcmp, false, NULL);
 }