]> git.proxmox.com Git - mirror_lxc.git/commitdiff
confile: parse idmap=<path> mount option for rootfs
authorChristian Brauner <christian.brauner@ubuntu.com>
Wed, 17 Mar 2021 09:45:29 +0000 (10:45 +0100)
committerChristian Brauner <christian.brauner@ubuntu.com>
Wed, 21 Apr 2021 08:05:58 +0000 (10:05 +0200)
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c

index c23bf0349f6c7b5b1f490f8c4855a2fd37b21fdb..562e232aa1467419276e65b594ab6f32dac8c50e 100644 (file)
@@ -2103,7 +2103,7 @@ const char *lxc_mount_options_info[LXC_MOUNT_MAX] = {
 };
 
 /* Remove "optional", "create=dir", and "create=file" from mntopt */
-void parse_lxc_mntopts(struct lxc_mount_options *opts, char *mnt_opts)
+int parse_lxc_mntopts(struct lxc_mount_options *opts, char *mnt_opts)
 {
 
        for (size_t i = LXC_MOUNT_CREATE_DIR; i < LXC_MOUNT_MAX; i++) {
@@ -2135,13 +2135,15 @@ void parse_lxc_mntopts(struct lxc_mount_options *opts, char *mnt_opts)
 
                        len = strlcpy(opts->userns_path, p2, idmap_path - p2 + 1);
                        if (len >= sizeof(opts->userns_path))
-                               WARN("Excessive idmap path length for \"idmap=<path>\" LXC specific mount option");
-                       else
-                               TRACE("Parse LXC specific mount option \"idmap=%s\"", opts->userns_path);
+                               return syserror_set(-EIO, "Excessive idmap path length for \"idmap=<path>\" LXC specific mount option");
+
+                       if (is_empty_string(opts->userns_path))
+                               return syserror_set(-EINVAL, "Missing idmap path for \"idmap=<path>\" LXC specific mount option");
+
+                       TRACE("Parse LXC specific mount option \"idmap=%s\"", opts->userns_path);
                        break;
                default:
-                       WARN("Unknown LXC specific mount option");
-                       break;
+                       return syserror_set(-EINVAL, "Unknown LXC specific mount option");
                }
 
                p2 = strchr(p, ',');
@@ -2150,6 +2152,8 @@ void parse_lxc_mntopts(struct lxc_mount_options *opts, char *mnt_opts)
                else
                        memmove(p, p2 + 1, strlen(p2 + 1) + 1);
        }
+
+       return 0;
 }
 
 static int mount_entry_create_dir_file(const struct mntent *mntent,
@@ -2227,7 +2231,10 @@ static inline int mount_entry_on_generic(struct mntent *mntent,
 
                return -1;
        }
-       parse_lxc_mntopts(&opts, mntent->mnt_opts);
+
+       ret = parse_lxc_mntopts(&opts, mntent->mnt_opts);
+       if (ret < 0)
+               return ret;
 
        ret = parse_propagationopts(mntent->mnt_opts, &pflags);
        if (ret < 0)
index a840228ffbfb92a00f8e8fa60f663a5d8b98d82d..91b191095c26dbbebff3800dc168447095331afb 100644 (file)
@@ -529,7 +529,7 @@ __hidden extern int userns_exec_full(struct lxc_conf *conf, int (*fn)(void *), v
                                     const char *fn_name);
 __hidden extern int parse_mntopts(const char *mntopts, unsigned long *mntflags, char **mntdata);
 __hidden extern int parse_propagationopts(const char *mntopts, unsigned long *pflags);
-__hidden extern void parse_lxc_mntopts(struct lxc_mount_options *opts, char *mnt_opts);
+__hidden extern int parse_lxc_mntopts(struct lxc_mount_options *opts, char *mnt_opts);
 __hidden extern void tmp_proc_unmount(struct lxc_conf *lxc_conf);
 __hidden extern void suggest_default_idmap(void);
 __hidden extern FILE *make_anonymous_mount_file(struct lxc_list *mount, bool include_nesting_helpers);
index baa691245b4e45623ddd50624c92e4af91509b95..e987812e4b46a9c35472c6383c227b1fad0cb22d 100644 (file)
@@ -2790,7 +2790,7 @@ static int set_config_rootfs_mount(const char *key, const char *value,
 static int set_config_rootfs_options(const char *key, const char *value,
                                     struct lxc_conf *lxc_conf, void *data)
 {
-       __do_free char *mdata = NULL, *opts = NULL;
+       __do_free char *dup = NULL, *mdata = NULL, *opts = NULL;
        unsigned long mflags = 0, pflags = 0;
        struct lxc_rootfs *rootfs = &lxc_conf->rootfs;
        int ret;
@@ -2799,18 +2799,30 @@ static int set_config_rootfs_options(const char *key, const char *value,
        if (lxc_config_value_empty(value))
                return 0;
 
-       ret = parse_mntopts(value, &mflags, &mdata);
+       dup = strdup(value);
+       if (!dup)
+               return -ENOMEM;
+
+       ret = parse_lxc_mntopts(&rootfs->mnt_opts, dup);
+       if (ret < 0)
+               return ret;
+
+       ret = parse_mntopts(dup, &mflags, &mdata);
        if (ret < 0)
                return ret_errno(EINVAL);
 
-       ret = parse_propagationopts(value, &pflags);
+       ret = parse_propagationopts(dup, &pflags);
        if (ret < 0)
                return ret_errno(EINVAL);
 
-       ret = set_config_string_item(&opts, value);
+       ret = set_config_string_item(&opts, dup);
        if (ret < 0)
                return ret_errno(ENOMEM);
 
+       if (rootfs->mnt_opts.create_dir || rootfs->mnt_opts.create_file ||
+           rootfs->mnt_opts.optional || rootfs->mnt_opts.relative)
+               return syserror_set(-EINVAL, "Invalid LXC specifc mount option for rootfs mount");
+
        rootfs->mountflags      = mflags | pflags;
        rootfs->options         = move_ptr(opts);
        rootfs->data            = move_ptr(mdata);