From 0e932812ae2ac4dec58e413c0d95d581385b9756 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Wed, 29 Nov 2023 15:57:04 +0100 Subject: [PATCH] conf: fix ephemeral copies Don't rely on rootfs->bdev_type because that may be NULL. Use storage->type instead which can't be NULL. Co-Developed-by: Mathias Gibbens Signed-off-by: Mathias Gibbens Reported-by: Mathias Gibbens Signed-off-by: Christian Brauner --- src/lxc/conf.c | 21 ++++++++++++--------- src/lxc/conf.h | 4 ++-- src/lxc/confile.c | 4 ++-- src/lxc/storage/storage.c | 4 ++-- src/lxc/storage/storage.h | 2 +- 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index 9c2d6b66a9..a7775059df 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -536,16 +536,21 @@ int lxc_rootfs_init(struct lxc_conf *conf, bool userns) struct stat st; struct statfs stfs; struct lxc_rootfs *rootfs = &conf->rootfs; + const char *type; ret = lxc_storage_prepare(conf); if (ret) return syserror_set(-EINVAL, "Failed to prepare rootfs storage"); + type = rootfs->storage->type; + + if (!type) + return syserror_set(-EINVAL, "Storage type neither set nor automatically detected"); if (!is_empty_string(rootfs->mnt_opts.userns_path)) { if (!rootfs->path) return syserror_set(-EINVAL, "Idmapped rootfs currently only supported with separate rootfs for container"); - if (rootfs->bdev_type && !strequal(rootfs->bdev_type, "dir")) + if (type && !strequal(type, "dir")) return syserror_set(-EINVAL, "Idmapped rootfs currently only supports the \"dir\" storage driver"); } @@ -555,14 +560,12 @@ int lxc_rootfs_init(struct lxc_conf *conf, bool userns) if (userns) return log_trace(0, "Not pinning because container runs in user namespace"); - if (rootfs->bdev_type) { - if (strequal(rootfs->bdev_type, "overlay") || - strequal(rootfs->bdev_type, "overlayfs")) - return log_trace_errno(0, EINVAL, "Not pinning on stacking filesystem"); + if (strequal(type, "overlay") || + strequal(type, "overlayfs")) + return log_trace_errno(0, EINVAL, "Not pinning on stacking filesystem"); - if (strequal(rootfs->bdev_type, "zfs")) - return log_trace_errno(0, EINVAL, "Not pinning on ZFS filesystem"); - } + if (strequal(type, "zfs")) + return log_trace_errno(0, EINVAL, "Not pinning on ZFS filesystem"); dfd_path = open_at(-EBADF, rootfs->path, PROTECT_OPATH_FILE, 0, 0); if (dfd_path < 0) @@ -4831,8 +4834,8 @@ void lxc_conf_free(struct lxc_conf *conf) if (current_config == conf) current_config = NULL; lxc_terminal_conf_free(&conf->console); + free(conf->rootfs.__bdev_type); free(conf->rootfs.mount); - free(conf->rootfs.bdev_type); free(conf->rootfs.path); put_lxc_rootfs(&conf->rootfs, true); free(conf->logfile); diff --git a/src/lxc/conf.h b/src/lxc/conf.h index 185e0b35db..4ad8970443 100644 --- a/src/lxc/conf.h +++ b/src/lxc/conf.h @@ -233,7 +233,7 @@ struct lxc_mount_options { * @path : the rootfs source (directory or device) * @mount : where it is mounted * @buf : static buffer to construct paths - * @bdev_type : optional backing store type + * @__bdev_type : optional backing store type * @managed : whether it is managed by LXC * @dfd_mnt : fd for @mount * @dfd_dev : fd for /dev of the container @@ -251,7 +251,7 @@ struct lxc_rootfs { int dfd_dev; char buf[PATH_MAX]; - char *bdev_type; + char *__bdev_type; bool managed; struct lxc_mount_options mnt_opts; struct lxc_storage *storage; diff --git a/src/lxc/confile.c b/src/lxc/confile.c index 7a8a534186..89d50f35d3 100644 --- a/src/lxc/confile.c +++ b/src/lxc/confile.c @@ -2795,14 +2795,14 @@ static int set_config_rootfs_path(const char *key, const char *value, return ret_errno(ENOMEM); /* Split : into and - * . Set "rootfs.bdev_type" to and + * . Set "rootfs.__bdev_type" to and * "rootfs.path" to . */ tmp = strchr(dup, ':'); if (tmp) { *tmp = '\0'; - ret = set_config_path_item(&lxc_conf->rootfs.bdev_type, dup); + ret = set_config_path_item(&lxc_conf->rootfs.__bdev_type, dup); if (ret < 0) return ret_errno(ENOMEM); diff --git a/src/lxc/storage/storage.c b/src/lxc/storage/storage.c index 1f48eac3e5..497cad7882 100644 --- a/src/lxc/storage/storage.c +++ b/src/lxc/storage/storage.c @@ -215,7 +215,7 @@ static const struct lxc_storage_type *storage_query(struct lxc_conf *conf) size_t i; const struct lxc_storage_type *bdev; const char *path = conf->rootfs.path; - const char *type = conf->rootfs.bdev_type; + const char *type = conf->rootfs.__bdev_type; bdev = get_storage_by_name(path, type); if (bdev) @@ -641,7 +641,7 @@ struct lxc_storage *storage_init(struct lxc_conf *conf) bool storage_lxc_is_dir(struct lxc_conf *conf) { struct lxc_storage *orig; - char *type = conf->rootfs.bdev_type; + const char *type = conf->rootfs.__bdev_type; bool bret = false; if (type) diff --git a/src/lxc/storage/storage.h b/src/lxc/storage/storage.h index a3873fa80e..f8b0d1a878 100644 --- a/src/lxc/storage/storage.h +++ b/src/lxc/storage/storage.h @@ -98,7 +98,7 @@ struct lxc_storage { * trust the config file. If the config file key * lxc.rootfs.path is set to : * the confile parser will have split this into - * and and set the member in the + * and and set the <__bdev_type> member in the * lxc_rootfs struct to and the member * will be set to a clean without the prefix. This is the new, clean way of handling storage