From 53ca847c8d21b1e422745a221d49ddf61679d4dd Mon Sep 17 00:00:00 2001 From: lifeng68 Date: Fri, 27 Nov 2020 16:02:25 +0800 Subject: [PATCH] mount: make possible to bind mount /proc and /sys/fs 1. add check whether have /proc mounts entry, if has, skip the auto mount proc 2. mount cgroup before do mount entrys 3. pass if the mount on top of /proc and the source of the mount is a proc filesystem Signed-off-by: lifeng68 --- src/lxc/conf.c | 95 +++++++++++++++++++++++++++++++++++++++++++++++--- src/lxc/path.c | 2 +- 2 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/lxc/conf.c b/src/lxc/conf.c index ce5bab9c5..c3610ae33 100644 --- a/src/lxc/conf.c +++ b/src/lxc/conf.c @@ -2581,7 +2581,7 @@ retry: /* isulad: checkMountDestination checks to ensure that the mount destination is not over the top of /proc. * dest is required to be an abs path and have any symlinks resolved before calling this function. */ -static int check_mount_destination(const char *rootfs, const char *dest) +static int check_mount_destination(const char *rootfs, const char *dest, const char *src) { const char *invalid_destinations[] = { "/proc", @@ -2641,10 +2641,28 @@ static int check_mount_destination(const char *rootfs, const char *dest) return -1; } relpath = path_relative(fullpath, dest); + DEBUG("dst path %s get relative path %s with full path %s,src:%s", dest, relpath, fullpath, src); free(fullpath); - if (!relpath) + if (!relpath) { + ERROR("Failed to get relpath for %s related to %s", dest, fullpath); return -1; - if (!strcmp(relpath, ".") || strncmp(relpath, "..", 2)) { + } + // pass if the mount path is outside of invalid proc + if (strncmp(relpath, "..", 2) == 0) { + free(relpath); + continue; + } + if (strcmp(relpath, ".") == 0) { + if (src == NULL) { + free(relpath); + continue; + } + // pass if the mount on top of /proc and the source of the mount is a proc filesystem + if (has_fs_type(src, PROC_SUPER_MAGIC)) { + WARN("src %s is proc allow mount on-top of %s", src, *invalid); + free(relpath); + continue; + } ERROR("%s cannot be mounted because it is located inside %s", dest, *invalid); free(relpath); return -1; @@ -2706,7 +2724,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, } dest = rpath; - ret = check_mount_destination(rootfs_path, dest); + ret = check_mount_destination(rootfs_path, dest, mntent->mnt_fsname); if (ret) { ERROR("Mount destination is invalid: '%s'", dest); lxc_write_error_message(rootfs->errfd, "%s:%d: mount destination is invalid: '%s'.", @@ -3119,6 +3137,52 @@ static bool need_setup_dev(const struct lxc_conf *conf, struct lxc_list *mount) return true; } } + +static bool have_proc_bind_mount_entry(FILE *file) +{ + bool have_bind_proc = false; + char buf[PATH_MAX] = { 0 }; + struct mntent mntent; + + while (getmntent_r(file, &mntent, buf, sizeof(buf))) { + mntent.mnt_dir = lxc_string_replace(SPACE_MAGIC_STR, " ", mntent.mnt_dir); + if(mntent.mnt_dir == NULL) { + SYSERROR("memory allocation error"); + continue; + } + + DEBUG("parsed mnt %s, %s, %s", mntent.mnt_fsname, mntent.mnt_dir, mntent.mnt_type); + + if (strcmp(mntent.mnt_dir, "proc") == 0 && strcmp(mntent.mnt_type, "bind") == 0) { + have_bind_proc = true; + } + + free(mntent.mnt_dir); + mntent.mnt_dir = NULL; + + if (have_bind_proc) + return true; + } + + return false; +} + +// returns true if /proc needs to be set up. +static bool need_setup_proc(const struct lxc_conf *conf, struct lxc_list *mount) +{ + __do_fclose FILE *f = NULL; + + f = make_anonymous_mount_file(mount, conf->lsm_aa_allow_nesting); + if (f == NULL) + return true; + + if (have_proc_bind_mount_entry(f)) { + return false; + } else { + return true; + } +} + #endif static int parse_cap(const char *cap) @@ -4870,6 +4934,7 @@ int lxc_setup(struct lxc_handler *handler) char *keyring_context = NULL; #ifdef HAVE_ISULAD bool setup_dev = true; + bool setup_proc = true; #endif ret = lxc_setup_rootfs_prepare_root(lxc_conf, name, lxcpath); @@ -4930,6 +4995,17 @@ int lxc_setup(struct lxc_handler *handler) ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & ~LXC_AUTO_CGROUP_MASK, handler); if (ret < 0) return log_error(-1, "Failed to setup first automatic mounts"); + +#ifdef HAVE_ISULAD + /* Now mount only cgroups, if wanted. Before, /sys could not have been + * mounted. It is guaranteed to be mounted now either through + * automatically or via fstab entries. + */ + ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler); + if (ret < 0) + return log_error(-1, "Failed to setup remaining automatic mounts"); +#endif + #ifdef HAVE_ISULAD ret = setup_mount(lxc_conf, &lxc_conf->rootfs, lxc_conf->fstab, name, lxcpath, lxc_conf->lsm_se_mount_context); #else @@ -4950,6 +5026,7 @@ int lxc_setup(struct lxc_handler *handler) return log_error(-1, "Failed to setup mount entries"); #ifdef HAVE_ISULAD setup_dev = need_setup_dev(lxc_conf, &lxc_conf->mount_list); + setup_proc = need_setup_proc(lxc_conf, &lxc_conf->mount_list); #endif } @@ -4975,6 +5052,7 @@ int lxc_setup(struct lxc_handler *handler) } } +#ifndef HAVE_ISULAD /* Now mount only cgroups, if wanted. Before, /sys could not have been * mounted. It is guaranteed to be mounted now either through * automatically or via fstab entries. @@ -4982,6 +5060,7 @@ int lxc_setup(struct lxc_handler *handler) ret = lxc_mount_auto_mounts(lxc_conf, lxc_conf->auto_mounts & LXC_AUTO_CGROUP_MASK, handler); if (ret < 0) return log_error(-1, "Failed to setup remaining automatic mounts"); +#endif ret = run_lxc_hooks(name, "mount", lxc_conf, NULL); if (ret < 0) @@ -5026,9 +5105,17 @@ int lxc_setup(struct lxc_handler *handler) if (ret < 0) return log_error(-1, "Failed to setup \"/dev\" symlinks"); +#ifdef HAVE_ISULAD + if (setup_proc) { + ret = lxc_create_tmp_proc_mount(lxc_conf); + if (ret < 0) + return log_error(-1, "Failed to \"/proc\" LSMs"); + } +#else ret = lxc_create_tmp_proc_mount(lxc_conf); if (ret < 0) return log_error(-1, "Failed to \"/proc\" LSMs"); +#endif #ifdef HAVE_ISULAD /* Ask father to run oci prestart hooks and wait for him to finish. */ diff --git a/src/lxc/path.c b/src/lxc/path.c index 65b8aadbf..46256cb26 100644 --- a/src/lxc/path.c +++ b/src/lxc/path.c @@ -652,4 +652,4 @@ char *path_relative(const char *basepath, const char *targpath) } return safe_strdup(targ + t0); -} +} \ No newline at end of file -- 2.25.1