};
/* 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++) {
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, ',');
else
memmove(p, p2 + 1, strlen(p2 + 1) + 1);
}
+
+ return 0;
}
static int mount_entry_create_dir_file(const 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)
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);
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;
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);