From: Christian Brauner Date: Wed, 17 Mar 2021 09:45:29 +0000 (+0100) Subject: confile: parse idmap= mount option for rootfs X-Git-Tag: lxc-5.0.0~197^2~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=16fcdacc241a9c03bc4c83fdf16d6832e1afc1ba;p=thirdparty%2Flxc.git confile: parse idmap= mount option for rootfs Signed-off-by: Christian Brauner --- diff --git a/src/lxc/conf.c b/src/lxc/conf.c index c23bf0349..562e232aa 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -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=\" 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=\" LXC specific mount option"); + + if (is_empty_string(opts->userns_path)) + return syserror_set(-EINVAL, "Missing idmap path for \"idmap=\" 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) diff --git a/src/lxc/conf.h b/src/lxc/conf.h index a840228ff..91b191095 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -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); diff --git a/src/lxc/confile.c b/src/lxc/confile.c index baa691245..e987812e4 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -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);