diff --git a/0002-add-mount-label-for-rootfs.patch b/0002-add-mount-label-for-rootfs.patch new file mode 100644 index 0000000000000000000000000000000000000000..f856f52db47b3c8dc468b7a1590f0fa8d81441e6 --- /dev/null +++ b/0002-add-mount-label-for-rootfs.patch @@ -0,0 +1,1214 @@ +From 0b8bc902c0c7acb54efb1fd4be5121dbf9a08598 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Wed, 15 Jul 2020 16:09:35 +0800 +Subject: [PATCH 2/5] add mount label for rootfs + +Signed-off-by: wujing +--- + src/lxc/cgroups/cgfsng.c | 59 +++++----- + src/lxc/conf.c | 209 +++++++++++++++++++++++++++++++---- + src/lxc/conf.h | 25 +++-- + src/lxc/confile.c | 27 ++++- + src/lxc/lsm/lsm.c | 20 ++++ + src/lxc/lsm/lsm.h | 8 ++ + src/lxc/lsm/selinux.c | 227 +++++++++++++++++++++++++++++++++++++++ + src/lxc/utils.c | 70 ++++++++++++ + src/lxc/utils.h | 6 ++ + 9 files changed, 591 insertions(+), 60 deletions(-) + +diff --git a/src/lxc/cgroups/cgfsng.c b/src/lxc/cgroups/cgfsng.c +index 4a0961f1..1ff3d981 100644 +--- a/src/lxc/cgroups/cgfsng.c ++++ b/src/lxc/cgroups/cgfsng.c +@@ -2133,7 +2133,7 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, + } + ret = safe_mount(NULL, tmpfspath, "tmpfs", + MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME, +- "size=10240k,mode=755", root); ++ "size=10240k,mode=755", root, handler->conf->lsm_se_mount_context); + if (ret < 0) + goto on_error; + +@@ -2244,37 +2244,42 @@ __cgfsng_ops static bool cgfsng_mount(struct cgroup_ops *ops, + } + } + +- // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container +- if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) { +- // isulad: don't use the unified hierarchy for the systemd cgroup +- unifiedpath = must_make_path(root, "/sys/fs/cgroup/unified", NULL); +- if (dir_exists(unifiedpath)) { +- ret = umount2(unifiedpath, MNT_DETACH); +- if (ret < 0) { +- SYSERROR("Failed to umount /sys/fs/cgroup/unified."); +- goto on_error; +- } +- } +- +- systemdpath = must_make_path(root, "/sys/fs/cgroup/systemd", NULL); +- ret = mount(systemdpath, systemdpath, "bind", +- MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_RELATIME|MS_BIND|MS_REMOUNT, NULL); +- if (ret < 0) { +- SYSERROR("Failed to remount /sys/fs/cgroup/systemd."); +- goto on_error; +- } +- } ++ // isulad: remount /sys/fs/cgroup/systemd to readwrite for system container ++ if (handler->conf->systemd != NULL && strcmp(handler->conf->systemd, "true") == 0) ++ { ++ unifiedpath = must_make_path(root, "/sys/fs/cgroup/unified", NULL); ++ if (dir_exists(unifiedpath)) ++ { ++ ret = umount2(unifiedpath, MNT_DETACH); ++ if (ret < 0) ++ { ++ SYSERROR("Failed to umount /sys/fs/cgroup/unified."); ++ goto on_error; ++ } ++ } ++ ++ systemdpath = must_make_path(root, "/sys/fs/cgroup/systemd", NULL); ++ ret = mount(systemdpath, systemdpath, "bind", ++ MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_RELATIME | MS_BIND | MS_REMOUNT, NULL); ++ if (ret < 0) ++ { ++ SYSERROR("Failed to remount /sys/fs/cgroup/systemd."); ++ goto on_error; ++ } ++ } + + retval = true; + + on_error: + free(tmpfspath); +- if (systemdpath != NULL) { +- free(systemdpath); +- } +- if (unifiedpath != NULL) { +- free(unifiedpath); +- } ++ if (systemdpath != NULL) ++ { ++ free(systemdpath); ++ } ++ if (unifiedpath != NULL) ++ { ++ free(unifiedpath); ++ } + lxc_free_array((void **)merged, free); + return retval; + } +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 0744c19b..7e4af0a9 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -699,9 +699,15 @@ static int lxc_mount_auto_mounts(struct lxc_conf *conf, int flags, struct lxc_ha + + mflags = add_required_remount_flags(source, destination, + default_mounts[i].flags); ++#ifdef HAVE_ISULAD ++ r = safe_mount(source, destination, default_mounts[i].fstype, ++ mflags, default_mounts[i].options, ++ conf->rootfs.path ? conf->rootfs.mount : NULL, NULL); ++#else + r = safe_mount(source, destination, default_mounts[i].fstype, + mflags, default_mounts[i].options, + conf->rootfs.path ? conf->rootfs.mount : NULL); ++#endif + saved_errno = errno; + if (r < 0 && errno == ENOENT) { + INFO("Mount source or target for \"%s\" on \"%s\" does not exist. Skipping", source, destination); +@@ -1076,7 +1082,7 @@ on_error: + */ + #ifdef HAVE_ISULAD + static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, +- int autodevtmpfssize, const char *lxcpath, char *systemd) ++ int autodevtmpfssize, const char *lxcpath, char *systemd, const char *mount_label) + #else + static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + int autodevtmpfssize, const char *lxcpath) +@@ -1118,7 +1124,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + } + } else { + ret = safe_mount("none", path, "tmpfs", 0, mount_options, +- rootfs->path ? rootfs->mount : NULL); ++ rootfs->path ? rootfs->mount : NULL, mount_label); + if (ret < 0) { + SYSERROR("Failed to mount tmpfs on \"%s\"", path); + goto reset_umask; +@@ -1127,7 +1133,7 @@ static int mount_autodev(const char *name, const struct lxc_rootfs *rootfs, + } + #else + ret = safe_mount("none", path, "tmpfs", 0, mount_options, +- rootfs->path ? rootfs->mount : NULL ); ++ rootfs->path ? rootfs->mount : NULL); + if (ret < 0) { + SYSERROR("Failed to mount tmpfs on \"%s\"", path); + goto reset_umask; +@@ -1183,8 +1189,11 @@ enum { + LXC_DEVNODE_PARTIAL, + LXC_DEVNODE_OPEN, + }; +- ++#ifdef HAVE_ISULAD ++static int lxc_fill_autodev(const struct lxc_rootfs *rootfs, const char *mount_label) ++#else + static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) ++#endif + { + int i, ret; + char path[PATH_MAX]; +@@ -1260,9 +1269,13 @@ static int lxc_fill_autodev(const struct lxc_rootfs *rootfs) + ret = snprintf(hostpath, PATH_MAX, "/dev/%s", device->name); + if (ret < 0 || ret >= PATH_MAX) + return -1; +- ++#ifdef HAVE_ISULAD ++ ret = safe_mount(hostpath, path, 0, MS_BIND, NULL, ++ rootfs->path ? rootfs->mount : NULL, mount_label); ++#else + ret = safe_mount(hostpath, path, 0, MS_BIND, NULL, + rootfs->path ? rootfs->mount : NULL); ++#endif + if (ret < 0) + return log_error_errno(-1, errno, "Failed to bind mount host device node \"%s\" onto \"%s\"", + hostpath, path); +@@ -1818,17 +1831,34 @@ static int lxc_setup_devpts(struct lxc_conf *conf) + { + int ret; + char **opts; ++#ifdef HAVE_ISULAD ++ __do_free char *devpts_mntopts = NULL; ++#else + char devpts_mntopts[256]; ++#endif + char *mntopt_sets[5]; + char default_devpts_mntopts[256] = "gid=5,newinstance,ptmxmode=0666,mode=0620"; + + if (conf->pty_max <= 0) + return log_debug(0, "No new devpts instance will be mounted since no pts devices are requested"); + ++#ifdef HAVE_ISULAD ++ if (conf->lsm_se_mount_context != NULL) { ++ if (asprintf(&devpts_mntopts, "%s,max=%zu,context=\"%s\"", ++ default_devpts_mntopts, conf->pty_max, conf->lsm_se_mount_context) < 0) { ++ return -1; ++ } ++ } else { ++ if (asprintf(&devpts_mntopts, "%s,max=%zu", default_devpts_mntopts, conf->pty_max) < 0) { ++ return -1; ++ } ++ } ++#else + ret = snprintf(devpts_mntopts, sizeof(devpts_mntopts), "%s,max=%zu", + default_devpts_mntopts, conf->pty_max); + if (ret < 0 || (size_t)ret >= sizeof(devpts_mntopts)) + return -1; ++#endif + + (void)umount2("/dev/pts", MNT_DETACH); + +@@ -1917,9 +1947,13 @@ static int setup_personality(int persona) + + return 0; + } +- ++#ifdef HAVE_ISULAD ++static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, ++ const struct lxc_terminal *console, const char *mount_label) ++#else + static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, + const struct lxc_terminal *console) ++#endif + { + int ret; + char path[PATH_MAX]; +@@ -1956,8 +1990,12 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, + ret = fchmod(console->slave, S_IXUSR | S_IXGRP); + if (ret < 0) + return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name); +- ++#ifdef HAVE_ISULAD ++ // ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path, mount_label); ++ ret = safe_mount(console->name, path, "bind", MS_BIND, 0, rootfs_path, mount_label); ++#else + ret = safe_mount(console->name, path, "none", MS_BIND, 0, rootfs_path); ++#endif + if (ret < 0) + return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, path); + #ifdef HAVE_ISULAD +@@ -1967,9 +2005,15 @@ static int lxc_setup_dev_console(const struct lxc_rootfs *rootfs, + return 0; + } + ++#ifdef HAVE_ISULAD ++static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, ++ const struct lxc_terminal *console, ++ char *ttydir, const char *mount_label) ++#else + static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, + const struct lxc_terminal *console, + char *ttydir) ++#endif + { + int ret; + char path[PATH_MAX], lxcpath[PATH_MAX]; +@@ -2020,7 +2064,11 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, + return log_error_errno(-errno, errno, "Failed to set mode \"0%o\" to \"%s\"", S_IXUSR | S_IXGRP, console->name); + + /* bind mount console->name to '/dev//console' */ ++#ifdef HAVE_ISULAD ++ ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path, mount_label); ++#else + ret = safe_mount(console->name, lxcpath, "none", MS_BIND, 0, rootfs_path); ++#endif + if (ret < 0) + return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, lxcpath); + DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath); +@@ -2029,7 +2077,11 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, + #endif + + /* bind mount '/dev//console' to '/dev/console' */ ++#ifdef HAVE_ISULAD ++ ret = safe_mount(lxcpath, path, "none", MS_BIND, 0, rootfs_path, mount_label); ++#else + ret = safe_mount(lxcpath, path, "none", MS_BIND, 0, rootfs_path); ++#endif + if (ret < 0) + return log_error_errno(-1, errno, "Failed to mount \"%s\" on \"%s\"", console->name, lxcpath); + DEBUG("Mounted \"%s\" onto \"%s\"", console->name, lxcpath); +@@ -2038,15 +2090,26 @@ static int lxc_setup_ttydir_console(const struct lxc_rootfs *rootfs, + return 0; + } + ++#ifdef HAVE_ISULAD + static int lxc_setup_console(const struct lxc_rootfs *rootfs, +- const struct lxc_terminal *console, char *ttydir) ++ const struct lxc_terminal *console, char *ttydir, const char *mount_label) + { ++ if (!ttydir) ++ return lxc_setup_dev_console(rootfs, console, mount_label); + ++ return lxc_setup_ttydir_console(rootfs, console, ttydir, mount_label); ++} ++#else ++static int lxc_setup_console(const struct lxc_rootfs *rootfs, ++ const struct lxc_terminal *console, char *ttydir) ++{ + if (!ttydir) + return lxc_setup_dev_console(rootfs, console); + + return lxc_setup_ttydir_console(rootfs, console, ttydir); + } ++#endif ++ + #ifdef HAVE_ISULAD + static void parse_mntopt(char *opt, unsigned long *mflags, unsigned long *pflags, char **data, size_t size) + { +@@ -2226,10 +2289,17 @@ int parse_propagationopts(const char *mntopts, unsigned long *pflags) + return 0; + } + ++#ifdef HAVE_ISULAD ++static int mount_entry(const char *fsname, const char *target, ++ const char *fstype, unsigned long mountflags, ++ unsigned long pflags, const char *data, bool optional, ++ bool dev, bool relative, const char *rootfs, const char *mount_label) ++#else + static int mount_entry(const char *fsname, const char *target, + const char *fstype, unsigned long mountflags, + unsigned long pflags, const char *data, bool optional, + bool dev, bool relative, const char *rootfs) ++#endif + { + int ret; + char srcbuf[PATH_MAX]; +@@ -2245,8 +2315,13 @@ static int mount_entry(const char *fsname, const char *target, + srcpath = srcbuf; + } + ++#ifdef HAVE_ISULAD ++ ret = safe_mount(srcpath, target, fstype, mountflags & ~MS_REMOUNT, data, ++ rootfs, mount_label); ++#else + ret = safe_mount(srcpath, target, fstype, mountflags & ~MS_REMOUNT, data, + rootfs); ++#endif + if (ret < 0) { + if (optional) + return log_info_errno(0, errno, "Failed to mount \"%s\" on \"%s\" (optional)", +@@ -2579,11 +2654,20 @@ static int check_mount_destination(const char *rootfs, const char *dest) + + /* rootfs, lxc_name, and lxc_path can be NULL when the container is created + * without a rootfs. */ ++#ifdef HAVE_ISULAD ++static inline int mount_entry_on_generic(struct mntent *mntent, ++ const char *path, ++ const struct lxc_rootfs *rootfs, ++ const char *lxc_name, ++ const char *lxc_path, ++ const char *mount_label) ++#else + static inline int mount_entry_on_generic(struct mntent *mntent, + const char *path, + const struct lxc_rootfs *rootfs, + const char *lxc_name, + const char *lxc_path) ++#endif + { + __do_free char *mntdata = NULL; + unsigned long mntflags = 0, pflags = 0; +@@ -2655,7 +2739,7 @@ static inline int mount_entry_on_generic(struct mntent *mntent, + mntent->mnt_opts, rootfs_path); + } else { + ret = mount_entry(mntent->mnt_fsname, dest, mntent->mnt_type, mntflags, +- pflags, mntdata, optional, dev, relative, rootfs_path); ++ pflags, mntdata, optional, dev, relative, rootfs_path, mount_label); + } + + if (ret < 0) { +@@ -2695,13 +2779,25 @@ static inline int mount_entry_on_systemfs(struct mntent *mntent) + if (ret < 0 || ret >= sizeof(path)) + return -1; + ++#ifdef HAVE_ISULAD ++ return mount_entry_on_generic(mntent, path, NULL, NULL, NULL, NULL); ++#else + return mount_entry_on_generic(mntent, path, NULL, NULL, NULL); ++#endif + } + ++#ifdef HAVE_ISULAD ++static int mount_entry_on_absolute_rootfs(struct mntent *mntent, ++ const struct lxc_rootfs *rootfs, ++ const char *lxc_name, ++ const char *lxc_path, ++ const char *mount_label) ++#else + static int mount_entry_on_absolute_rootfs(struct mntent *mntent, + const struct lxc_rootfs *rootfs, + const char *lxc_name, + const char *lxc_path) ++#endif + { + int offset; + char *aux; +@@ -2736,14 +2832,25 @@ skipabs: + ret = snprintf(path, PATH_MAX, "%s/%s", rootfs->mount, aux + offset); + if (ret < 0 || ret >= PATH_MAX) + return -1; +- ++#ifdef HAVE_ISULAD ++ return mount_entry_on_generic(mntent, path, rootfs, lxc_name, lxc_path, mount_label); ++#else + return mount_entry_on_generic(mntent, path, rootfs, lxc_name, lxc_path); ++#endif + } + ++#ifdef HAVE_ISULAD ++static int mount_entry_on_relative_rootfs(struct mntent *mntent, ++ const struct lxc_rootfs *rootfs, ++ const char *lxc_name, ++ const char *lxc_path, ++ const char *mount_label) ++#else + static int mount_entry_on_relative_rootfs(struct mntent *mntent, + const struct lxc_rootfs *rootfs, + const char *lxc_name, + const char *lxc_path) ++#endif + { + int ret; + char path[PATH_MAX]; +@@ -2753,12 +2860,22 @@ static int mount_entry_on_relative_rootfs(struct mntent *mntent, + if (ret < 0 || (size_t)ret >= sizeof(path)) + return -1; + ++#ifdef HAVE_ISULAD ++ return mount_entry_on_generic(mntent, path, rootfs, lxc_name, lxc_path, mount_label); ++#else + return mount_entry_on_generic(mntent, path, rootfs, lxc_name, lxc_path); ++#endif + } + ++#ifdef HAVE_ISULAD ++static int mount_file_entries(const struct lxc_conf *conf, ++ const struct lxc_rootfs *rootfs, FILE *file, ++ const char *lxc_name, const char *lxc_path, const char *mount_label) ++#else + static int mount_file_entries(const struct lxc_conf *conf, + const struct lxc_rootfs *rootfs, FILE *file, + const char *lxc_name, const char *lxc_path) ++#endif + { + char buf[PATH_MAX]; + struct mntent mntent; +@@ -2786,22 +2903,30 @@ static int mount_file_entries(const struct lxc_conf *conf, + free(mntent.mnt_fsname); + return -1; + } +-#endif + + if (!rootfs->path) + ret = mount_entry_on_systemfs(&mntent); + else if (mntent.mnt_dir[0] != '/') + ret = mount_entry_on_relative_rootfs(&mntent, rootfs, +- lxc_name, lxc_path); ++ lxc_name, lxc_path, mount_label); + else + ret = mount_entry_on_absolute_rootfs(&mntent, rootfs, +- lxc_name, lxc_path); ++ lxc_name, lxc_path, mount_label); + +-#ifdef HAVE_ISULAD + free(mntent.mnt_fsname); + mntent.mnt_fsname = NULL; + free(mntent.mnt_dir); + mntent.mnt_dir = NULL; ++#else ++ ++ if (!rootfs->path) ++ ret = mount_entry_on_systemfs(&mntent); ++ else if (mntent.mnt_dir[0] != '/') ++ ret = mount_entry_on_relative_rootfs(&mntent, rootfs, ++ lxc_name, lxc_path); ++ else ++ ret = mount_entry_on_absolute_rootfs(&mntent, rootfs, ++ lxc_name, lxc_path); + #endif + + if (ret < 0) +@@ -2822,9 +2947,15 @@ static inline void __auto_endmntent__(FILE **f) + + #define __do_endmntent __attribute__((__cleanup__(__auto_endmntent__))) + ++#ifdef HAVE_ISULAD ++static int setup_mount(const struct lxc_conf *conf, ++ const struct lxc_rootfs *rootfs, const char *fstab, ++ const char *lxc_name, const char *lxc_path, const char *mount_label) ++#else + static int setup_mount(const struct lxc_conf *conf, + const struct lxc_rootfs *rootfs, const char *fstab, + const char *lxc_name, const char *lxc_path) ++#endif + { + __do_endmntent FILE *f = NULL; + int ret; +@@ -2836,7 +2967,11 @@ static int setup_mount(const struct lxc_conf *conf, + if (!f) + return log_error_errno(-1, errno, "Failed to open \"%s\"", fstab); + ++#ifdef HAVE_ISULAD ++ ret = mount_file_entries(conf, rootfs, f, lxc_name, lxc_path, mount_label); ++#else + ret = mount_file_entries(conf, rootfs, f, lxc_name, lxc_path); ++#endif + if (ret < 0) + ERROR("Failed to set up mount entries"); + +@@ -2912,10 +3047,17 @@ FILE *make_anonymous_mount_file(struct lxc_list *mount, + return f; + } + ++#ifdef HAVE_ISULAD ++static int setup_mount_entries(const struct lxc_conf *conf, ++ const struct lxc_rootfs *rootfs, ++ struct lxc_list *mount, const char *lxc_name, ++ const char *lxc_path, const char *mount_label) ++#else + static int setup_mount_entries(const struct lxc_conf *conf, + const struct lxc_rootfs *rootfs, + struct lxc_list *mount, const char *lxc_name, + const char *lxc_path) ++#endif + { + __do_fclose FILE *f = NULL; + +@@ -2923,7 +3065,11 @@ static int setup_mount_entries(const struct lxc_conf *conf, + if (!f) + return -1; + ++#ifdef HAVE_ISULAD ++ return mount_file_entries(conf, rootfs, f, lxc_name, lxc_path, mount_label); ++#else + return mount_file_entries(conf, rootfs, f, lxc_name, lxc_path); ++#endif + } + + #ifdef HAVE_ISULAD +@@ -3892,8 +4038,11 @@ static int lxc_execute_bind_init(struct lxc_handler *handler) + if (ret < 0 && errno != EEXIST) + return log_error_errno(-1, errno, "Failed to create dummy \"%s\" file as bind mount target", destpath); + } +- ++#ifdef HAVE_ISULAD ++ ret = safe_mount(path, destpath, "none", MS_BIND, NULL, conf->rootfs.mount, conf->lsm_se_mount_context); ++#else + ret = safe_mount(path, destpath, "none", MS_BIND, NULL, conf->rootfs.mount); ++#endif + if (ret < 0) + return log_error_errno(-1, errno, "Failed to bind mount lxc.init.static into container"); + +@@ -4035,7 +4184,7 @@ static int lxc_setup_boot_id(void) + + #ifdef HAVE_ISULAD + /* isulad: setup devices which will be populated in the container.*/ +-static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list *devs) ++static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list *devs, const char *mount_label) + { + int ret = 0; + char *pathdirname = NULL; +@@ -4104,7 +4253,7 @@ static int setup_populate_devs(const struct lxc_rootfs *rootfs, struct lxc_list + } + fclose(pathfile); + if (safe_mount(hostpath, path, 0, MS_BIND, NULL, +- rootfs->path ? rootfs->mount : NULL) != 0) { ++ rootfs->path ? rootfs->mount : NULL, mount_label) != 0) { + SYSERROR("Failed bind mounting device %s from host into container", + dev_elem->name); + ret = -1; +@@ -4761,7 +4910,8 @@ int lxc_setup(struct lxc_handler *handler) + + if (lxc_conf->autodev > 0) { + #ifdef HAVE_ISULAD +- ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath, lxc_conf->systemd); ++ ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath, ++ lxc_conf->systemd, lxc_conf->lsm_se_mount_context); + #else + ret = mount_autodev(name, &lxc_conf->rootfs, lxc_conf->autodevtmpfssize, lxcpath); + #endif +@@ -4775,14 +4925,22 @@ 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 ++ ret = setup_mount(lxc_conf, &lxc_conf->rootfs, lxc_conf->fstab, name, lxcpath, lxc_conf->lsm_se_mount_context); ++#else + ret = setup_mount(lxc_conf, &lxc_conf->rootfs, lxc_conf->fstab, name, lxcpath); ++#endif + if (ret < 0) + return log_error(-1, "Failed to setup mounts"); + + if (!lxc_list_empty(&lxc_conf->mount_list)) { ++#ifdef HAVE_ISULAD ++ ret = setup_mount_entries(lxc_conf, &lxc_conf->rootfs, ++ &lxc_conf->mount_list, name, lxcpath, lxc_conf->lsm_se_mount_context); ++#else + ret = setup_mount_entries(lxc_conf, &lxc_conf->rootfs, + &lxc_conf->mount_list, name, lxcpath); ++#endif + if (ret < 0) + return log_error(-1, "Failed to setup mount entries"); + #ifdef HAVE_ISULAD +@@ -4828,8 +4986,11 @@ int lxc_setup(struct lxc_handler *handler) + ret = run_lxc_hooks(name, "autodev", lxc_conf, NULL); + if (ret < 0) + return log_error(-1, "Failed to run autodev hooks"); +- ++#ifdef HAVE_ISULAD ++ ret = lxc_fill_autodev(&lxc_conf->rootfs, lxc_conf->lsm_se_mount_context); ++#else + ret = lxc_fill_autodev(&lxc_conf->rootfs); ++#endif + if (ret < 0) + return log_error(-1, "Failed to populate \"/dev\""); + } +@@ -4837,7 +4998,7 @@ int lxc_setup(struct lxc_handler *handler) + #ifdef HAVE_ISULAD + /* isulad: setup devices which will be populated in the container. */ + if (!lxc_list_empty(&lxc_conf->populate_devs) && setup_dev) { +- if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs) != 0) { ++ if (setup_populate_devs(&lxc_conf->rootfs, &lxc_conf->populate_devs, lxc_conf->lsm_se_mount_context) != 0) { + return log_error(-1, "Failed to setup devices in the container"); + } + } +@@ -4846,9 +5007,13 @@ int lxc_setup(struct lxc_handler *handler) + /* Make sure any start hooks are in the container */ + if (!verify_start_hooks(lxc_conf)) + return log_error(-1, "Failed to verify start hooks"); +- ++#ifdef HAVE_ISULAD ++ ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, ++ lxc_conf->ttys.dir, lxc_conf->lsm_se_mount_context); ++#else + ret = lxc_setup_console(&lxc_conf->rootfs, &lxc_conf->console, + lxc_conf->ttys.dir); ++#endif + if (ret < 0) + return log_error(-1, "Failed to setup console"); + +diff --git a/src/lxc/conf.h b/src/lxc/conf.h +index 4b6409e3..c9265b65 100644 +--- a/src/lxc/conf.h ++++ b/src/lxc/conf.h +@@ -442,31 +442,36 @@ struct lxc_conf { + } shmount; + + #ifdef HAVE_ISULAD +- /* +- * isulad: support oci hook +- * */ ++ /* support oci hook */ + oci_runtime_spec_hooks *ocihooks; + +- /* isulad add: init args used to repalce init_cmd*/ ++ /* init args used to repalce init_cmd */ + char **init_argv; + size_t init_argc; + + gid_t *init_groups; + size_t init_groups_len; + +- /* populate devices*/ ++ /* populate devices */ + struct lxc_list populate_devs; +- mode_t umask; //umask value ++ mode_t umask; // umask value + + char *container_info_file; + +- int exit_fd; /* exit fifo fd*/ ++ /* exit fifo fd*/ ++ int exit_fd; ++ ++ /* record error messages */ ++ char *errmsg; + +- char *errmsg; /* record error messages */ ++ /* pipdfd for get error message of child or grandchild process */ ++ int errpipe[2]; + +- int errpipe[2];//pipdfd for get error message of child or grandchild process. ++ /* systemd value */ ++ char *systemd; + +- char *systemd; //systemd value ++ /* Linux Security Modules SELinux context for device mount */ ++ char *lsm_se_mount_context; + #endif + + }; +diff --git a/src/lxc/confile.c b/src/lxc/confile.c +index b1d101a9..f108b37b 100644 +--- a/src/lxc/confile.c ++++ b/src/lxc/confile.c +@@ -158,6 +158,7 @@ lxc_config_define(systemd); + lxc_config_define(console_log_driver); + lxc_config_define(console_syslog_tag); + lxc_config_define(console_syslog_facility); ++lxc_config_define(selinux_mount_context); + #endif + + /* +@@ -247,7 +248,7 @@ static struct lxc_config_t config_jump_table[] = { + { "lxc.net.veth.ipv6.route", set_config_net_veth_ipv6_route, get_config_net_veth_ipv6_route, clr_config_net_veth_ipv6_route, }, + { "lxc.net.", set_config_net_nic, get_config_net_nic, clr_config_net_nic, }, + { "lxc.net", set_config_net, get_config_net, clr_config_net, }, +- { "lxc.no_new_privs", set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, }, ++ { "lxc.no_new_privs", set_config_no_new_privs, get_config_no_new_privs, clr_config_no_new_privs, }, + { "lxc.prlimit", set_config_prlimit, get_config_prlimit, clr_config_prlimit, }, + { "lxc.pty.max", set_config_pty_max, get_config_pty_max, clr_config_pty_max, }, + { "lxc.rootfs.managed", set_config_rootfs_managed, get_config_rootfs_managed, clr_config_rootfs_managed, }, +@@ -282,6 +283,7 @@ static struct lxc_config_t config_jump_table[] = { + { "lxc.console.logdriver", set_config_console_log_driver, get_config_console_log_driver, clr_config_console_log_driver, }, + { "lxc.console.syslog_tag", set_config_console_syslog_tag, get_config_console_syslog_tag, clr_config_console_syslog_tag, }, + { "lxc.console.syslog_facility", set_config_console_syslog_facility, get_config_console_syslog_facility, clr_config_console_syslog_facility, }, ++ { "lxc.selinux.mount_context", set_config_selinux_mount_context, get_config_selinux_mount_context, clr_config_selinux_mount_context, }, + #endif + }; + +@@ -6685,6 +6687,16 @@ static int set_config_console_syslog_facility(const char *key, const char *value + return 0; + } + ++static int set_config_selinux_mount_context(const char *key, const char *value, ++ struct lxc_conf *lxc_conf, void *data) ++{ ++ if (value != NULL && strcmp(value, "unconfined_t") == 0) { ++ return set_config_string_item(&lxc_conf->lsm_se_mount_context, NULL); ++ } ++ ++ return set_config_string_item(&lxc_conf->lsm_se_mount_context, value); ++} ++ + static int get_config_console_log_driver(const char *key, char *retv, int inlen, + struct lxc_conf *c, void *data) + { +@@ -6703,6 +6715,12 @@ static int get_config_console_syslog_facility(const char *key, char *retv, int i + return lxc_get_conf_int(c, retv, inlen, c->console.log_syslog_facility); + } + ++static int get_config_selinux_mount_context(const char *key, char *retv, int inlen, ++ struct lxc_conf *c, void *data) ++{ ++ return lxc_get_conf_str(retv, inlen, c->lsm_se_mount_context); ++} ++ + static inline int clr_config_console_log_driver(const char *key, + struct lxc_conf *c, void *data) + { +@@ -6726,4 +6744,11 @@ static inline int clr_config_console_syslog_facility(const char *key, + return 0; + } + ++static inline int clr_config_selinux_mount_context(const char *key, ++ struct lxc_conf *c, void *data) ++{ ++ free(c->lsm_se_mount_context); ++ c->lsm_se_mount_context = NULL; ++ return 0; ++} + #endif +diff --git a/src/lxc/lsm/lsm.c b/src/lxc/lsm/lsm.c +index 553e0c99..2f87dd68 100644 +--- a/src/lxc/lsm/lsm.c ++++ b/src/lxc/lsm/lsm.c +@@ -168,6 +168,26 @@ int lsm_process_label_set(const char *label, struct lxc_conf *conf, + return drv->process_label_set(label, conf, on_exec); + } + ++#ifdef HAVE_ISULAD ++int lsm_file_label_set(const char *path, const char *label) ++{ ++ if (!drv) { ++ ERROR("LSM driver not inited"); ++ return -1; ++ } ++ return drv->file_label_set(path, label); ++} ++ ++int lsm_relabel(const char *path, const char *label, bool share) ++{ ++ if (!drv) { ++ ERROR("LSM driver not inited"); ++ return -1; ++ } ++ return drv->relabel(path, label, share); ++} ++#endif ++ + int lsm_process_prepare(struct lxc_conf *conf, const char *lxcpath) + { + if (!drv) { +diff --git a/src/lxc/lsm/lsm.h b/src/lxc/lsm/lsm.h +index ee578bb0..4872f559 100644 +--- a/src/lxc/lsm/lsm.h ++++ b/src/lxc/lsm/lsm.h +@@ -17,6 +17,10 @@ struct lsm_drv { + char *(*process_label_get)(pid_t pid); + int (*process_label_set)(const char *label, struct lxc_conf *conf, + bool on_exec); ++#ifdef HAVE_ISULAD ++ int (*file_label_set)(const char *path, const char *label); ++ int (*relabel)(const char *path, const char *label, bool share); ++#endif + int (*keyring_label_set)(char* label); + int (*prepare)(struct lxc_conf *conf, const char *lxcpath); + void (*cleanup)(struct lxc_conf *conf, const char *lxcpath); +@@ -32,6 +36,10 @@ extern int lsm_process_label_set(const char *label, struct lxc_conf *conf, + extern int lsm_process_label_fd_get(pid_t pid, bool on_exec); + extern int lsm_process_label_set_at(int label_fd, const char *label, + bool on_exec); ++#ifdef HAVE_ISULAD ++extern int lsm_file_label_set(const char *path, const char *label); ++extern int lsm_relabel(const char *path, const char *label, bool share); ++#endif + extern void lsm_process_cleanup(struct lxc_conf *conf, const char *lxcpath); + extern int lsm_keyring_label_set(char *label); + +diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c +index dba0ab58..5bc9843e 100644 +--- a/src/lxc/lsm/selinux.c ++++ b/src/lxc/lsm/selinux.c +@@ -16,6 +16,10 @@ + #include "log.h" + #include "lsm.h" + ++#ifdef HAVE_ISULAD ++#include ++#endif ++ + #define DEFAULT_LABEL "unconfined_t" + + lxc_log_define(selinux, lsm); +@@ -85,6 +89,225 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf, + return 0; + } + ++#ifdef HAVE_ISULAD ++/* ++ * selinux_file_label_set: Set SELinux context of a file ++ * ++ * @path : a file ++ * @label : label string ++ * ++ * Returns 0 on success, < 0 on failure ++ */ ++static int selinux_file_label_set(const char *path, const char *label) ++{ ++ int ret; ++ ++ if (path == NULL || label == NULL || strcmp(label, "unconfined_t") == 0) { ++ return 0; ++ } ++ ++ ret = lsetfilecon(path, label); ++ if (ret != 0) { ++ SYSERROR("Failed to setSELinux context to \"%s\": %s", label, path); ++ return -1; ++ } ++ ++ INFO("Changed SELinux context to \"%s\": %s", label, path); ++ return 0; ++} ++ ++/* ++ * is_exclude_relabel_path: Determine whether it is a excluded path to label ++ * ++ * @path : a file or directory ++ * ++ * Returns 0 on success, < 0 on failure ++ */ ++static bool is_exclude_relabel_path(const char *path) ++{ ++ const char *exclude_path[] = { "/", "/usr", "/etc", "/tmp", "/home", "/run", "/var", "/root" }; ++ size_t i; ++ ++ for (i = 0; i < sizeof(exclude_path) / sizeof(char *); i++) { ++ if (strcmp(path, exclude_path[i]) == 0) { ++ return true; ++ } ++ } ++ ++ return false; ++} ++ ++/* ++ * bad_prefix: Prevent users from relabing system files ++ * ++ * @path : a file or directory ++ * ++ * Returns 0 on success, < 0 on failure ++ */ ++static int bad_prefix(const char *fpath) ++{ ++ const char *bad_prefixes = "/usr"; ++ ++ if (fpath == NULL) { ++ ERROR("Empty file path"); ++ return -1; ++ } ++ ++ if (strncmp(fpath, bad_prefixes, strlen(bad_prefixes)) == 0) { ++ ERROR("relabeling content in %s is not allowed", bad_prefixes); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* ++ * recurse_set_file_label: Recursively label files or folders ++ * ++ * @path : a file or directory ++ * @label : label string ++ * ++ * Returns 0 on success, < 0 on failure ++ */ ++static int recurse_set_file_label(const char *basePath, const char *label) ++{ ++ int ret = 0; ++ DIR *dir = NULL; ++ struct dirent *ptr = NULL; ++ char base[PATH_MAX] = { 0 }; ++ ++ if ((dir = opendir(basePath)) == NULL) { ++ ERROR("Failed to Open dir: %s", basePath); ++ return -1; ++ } ++ ++ ret = lsetfilecon(basePath, label); ++ if (ret != 0) { ++ ERROR("Failed to set file label"); ++ goto out; ++ } ++ ++ while ((ptr = readdir(dir)) != NULL) { ++ if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { ++ continue; ++ } else { ++ int nret = snprintf(base, sizeof(base), "%s/%s", basePath, ptr->d_name); ++ if (nret < 0 || nret >= sizeof(base)) { ++ ERROR("Failed to get path"); ++ ret = -1; ++ goto out; ++ } ++ if (ptr->d_type == DT_DIR) { ++ ret = recurse_set_file_label(base, label); ++ if (ret != 0) { ++ ERROR("Failed to set dir label"); ++ goto out; ++ } ++ } else { ++ ret = lsetfilecon(base, label); ++ if (ret != 0) { ++ ERROR("Failed to set file label"); ++ goto out; ++ } ++ } ++ } ++ } ++ ++out: ++ closedir(dir); ++ return ret; ++} ++ ++/* ++ * selinux_chcon: Chcon changes the `fpath` file object to the SELinux label `label`. ++ * If `fpath` is a directory and `recurse`` is true, Chcon will walk the ++ * directory tree setting the label. ++ * ++ * @fpath : a file or directory ++ * @label : label string ++ * @recurse : whether to recurse ++ * ++ * Returns 0 on success, < 0 on failure ++ */ ++static int selinux_chcon(const char *fpath, const char *label, bool recurse) ++{ ++ struct stat s_buf; ++ ++ if (fpath == NULL) { ++ ERROR("Empty file path"); ++ return -1; ++ } ++ ++ if (label == NULL) { ++ return 0; ++ } ++ ++ if (bad_prefix(fpath) != 0) { ++ return -1; ++ } ++ if (stat(fpath, &s_buf) != 0) { ++ return -1; ++ } ++ if (recurse && S_ISDIR(s_buf.st_mode)) { ++ return recurse_set_file_label(fpath, label); ++ } ++ ++ if (lsetfilecon(fpath, label) != 0) { ++ ERROR("Failed to set file label"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/* ++ * selinux_relabel: Relabel changes the label of path to the filelabel string. ++ * It changes the MCS label to s0 if shared is true. ++ * This will allow all containers to share the content. ++ * ++ * @path : a file or directory ++ * @label : label string ++ * @shared : whether to use share mode ++ * ++ * Returns 0 on success, < 0 on failure ++ */ ++static int selinux_relabel(const char *path, const char *label, bool shared) ++{ ++ int ret = 0; ++ char *tmp_file_label = NULL; ++ ++ if (label == NULL) { ++ return 0; ++ } ++ ++ tmp_file_label = strdup(label); ++ if (is_exclude_relabel_path(path)) { ++ ERROR("SELinux relabeling of %s is not allowed", path); ++ ret = -1; ++ goto out; ++ } ++ ++ if (shared) { ++ context_t c = context_new(label); ++ context_range_set(c, "s0"); ++ free(tmp_file_label); ++ tmp_file_label = strdup(context_str(c)); ++ context_free(c); ++ } ++ ++ if (selinux_chcon(path, tmp_file_label, true) != 0) { ++ ERROR("Failed to modify %s's selinux context: %s", path, tmp_file_label); ++ ret = -1; ++ goto out; ++ } ++ ++out: ++ free(tmp_file_label); ++ return ret; ++} ++ ++#endif ++ + /* + * selinux_keyring_label_set: Set SELinux context that will be assigned to the keyring + * +@@ -103,6 +326,10 @@ static struct lsm_drv selinux_drv = { + .process_label_get = selinux_process_label_get, + .process_label_set = selinux_process_label_set, + .keyring_label_set = selinux_keyring_label_set, ++#ifdef HAVE_ISULAD ++ .file_label_set = selinux_file_label_set, ++ .relabel = selinux_relabel, ++#endif + }; + + struct lsm_drv *lsm_selinux_drv_init(void) +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 4e418fbb..032176b1 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -1097,6 +1097,37 @@ out: + return dirfd; + } + ++#ifdef HAVE_ISULAD ++static int format_mount_label(const char *data, const char *mount_label, char **mnt_opts) ++{ ++ int ret = 0; ++ ++ if (mount_label != NULL) { ++ if (data != NULL) { ++ ret = asprintf(mnt_opts, "%s,context=\"%s\"", data, mount_label); ++ } else { ++ ret = asprintf(mnt_opts, "context=\"%s\"", mount_label); ++ } ++ ++ return ret < 0 ? -1 : 0; ++ } ++ ++ *mnt_opts = data != NULL ? strdup(data) : NULL; ++ return 0; ++} ++ ++static int receive_mount_options(const char *data, const char *mount_label, ++ const char *fstype, char **mnt_opts) ++{ ++ // SELinux kernels don't support labeling of /proc or /sys ++ if (fstype != NULL && (strcmp(fstype, "proc") == 0 || strcmp(fstype, "sysfs") == 0)) { ++ return format_mount_label(data, NULL, mnt_opts); ++ } ++ ++ return format_mount_label(data, mount_label, mnt_opts); ++} ++#endif ++ + /* + * Safely mount a path into a container, ensuring that the mount target + * is under the container's @rootfs. (If @rootfs is NULL, then the container +@@ -1105,14 +1136,22 @@ out: + * CAVEAT: This function must not be used for other purposes than container + * setup before executing the container's init + */ ++#ifdef HAVE_ISULAD ++int safe_mount(const char *src, const char *dest, const char *fstype, ++ unsigned long flags, const void *data, const char *rootfs, const char *mount_label) ++#else + int safe_mount(const char *src, const char *dest, const char *fstype, + unsigned long flags, const void *data, const char *rootfs) ++#endif + { + int destfd, ret, saved_errno; + /* Only needs enough for /proc/self/fd/. */ + char srcbuf[50], destbuf[50]; + int srcfd = -1; + const char *mntsrc = src; ++#ifdef HAVE_ISULAD ++ __do_free char *mnt_opts = NULL; ++#endif + + if (!rootfs) + rootfs = ""; +@@ -1155,8 +1194,23 @@ int safe_mount(const char *src, const char *dest, const char *fstype, + return -EINVAL; + } + ++#ifdef HAVE_ISULAD ++ if (receive_mount_options(data, mount_label, fstype, &mnt_opts) != 0) { ++ ERROR("Failed to receive mount options"); ++ return -EINVAL; ++ } ++ ++ ret = mount(mntsrc, destbuf, fstype, flags, mnt_opts); ++ saved_errno = errno; ++ if (ret < 0 && strcmp(fstype, "mqueue") == 0) { ++ INFO("older kernels don't support labeling of /dev/mqueue, retry without selinux context"); ++ ret = mount(mntsrc, destbuf, fstype, flags, data); ++ saved_errno = errno; ++ } ++#else + ret = mount(mntsrc, destbuf, fstype, flags, data); + saved_errno = errno; ++#endif + if (srcfd != -1) + close(srcfd); + +@@ -1167,6 +1221,18 @@ int safe_mount(const char *src, const char *dest, const char *fstype, + return ret; + } + ++#ifdef HAVE_ISULAD ++ if (strcmp(fstype, "mqueue") == 0 && lsm_file_label_set(dest, mount_label) != 0) { ++ ERROR("Failed to set file label on %s", dest); ++ return -EINVAL; ++ } ++ ++ if (strcmp(fstype, "bind") == 0 && lsm_relabel(src, mount_label, false) != 0) { ++ ERROR("Failed to reabel %s with %s", src, mount_label); ++ return -EINVAL; ++ } ++#endif ++ + return 0; + } + +@@ -1233,7 +1299,11 @@ domount: + if (!strcmp(rootfs, "")) + ret = mount("proc", path, "proc", 0, NULL); + else ++#ifdef HAVE_ISULAD ++ ret = safe_mount("proc", path, "proc", 0, NULL, rootfs, NULL); ++#else + ret = safe_mount("proc", path, "proc", 0, NULL, rootfs); ++#endif + if (ret < 0) + return -1; + +diff --git a/src/lxc/utils.h b/src/lxc/utils.h +index 39ef5792..4d1c49ba 100644 +--- a/src/lxc/utils.h ++++ b/src/lxc/utils.h +@@ -220,9 +220,15 @@ extern char *choose_init(const char *rootfs); + extern bool switch_to_ns(pid_t pid, const char *ns); + extern char *get_template_path(const char *t); + extern int open_without_symlink(const char *target, const char *prefix_skip); ++#ifdef HAVE_ISULAD ++extern int safe_mount(const char *src, const char *dest, const char *fstype, ++ unsigned long flags, const void *data, ++ const char *rootfs, const char *mount_label); ++#else + extern int safe_mount(const char *src, const char *dest, const char *fstype, + unsigned long flags, const void *data, + const char *rootfs); ++#endif + extern int lxc_mount_proc_if_needed(const char *rootfs); + extern int open_devnull(void); + extern int set_stdfds(int fd); +-- +2.25.1 + diff --git a/0003-format-code-and-verify-mount-mode.patch b/0003-format-code-and-verify-mount-mode.patch new file mode 100644 index 0000000000000000000000000000000000000000..8a3198a210b0a73b9d3fc8927ac7eff91514b0a7 --- /dev/null +++ b/0003-format-code-and-verify-mount-mode.patch @@ -0,0 +1,423 @@ +From c0f37e083c49cfcb9441743a409fdee44d32d7c5 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Thu, 16 Jul 2020 16:39:35 +0800 +Subject: [PATCH 3/5] format code and verify mount mode + +Signed-off-by: wujing +--- + src/lxc/lsm/apparmor.c | 14 +++ + src/lxc/lsm/nop.c | 14 +++ + src/lxc/lsm/selinux.c | 242 +++++++++++++++++++++-------------------- + src/lxc/utils.c | 30 ++++- + 4 files changed, 182 insertions(+), 118 deletions(-) + +diff --git a/src/lxc/lsm/apparmor.c b/src/lxc/lsm/apparmor.c +index f251e5e7..591d37c2 100644 +--- a/src/lxc/lsm/apparmor.c ++++ b/src/lxc/lsm/apparmor.c +@@ -1186,6 +1186,16 @@ static int apparmor_process_label_set(const char *inlabel, struct lxc_conf *conf + return 0; + } + ++#ifdef HAVE_ISULAD ++static int apparmor_file_label_set(const char *path, const char *label) { ++ return 0; ++} ++ ++static int apparmor_relabel(const char *path, const char *label, bool shared) { ++ return 0; ++} ++#endif ++ + static struct lsm_drv apparmor_drv = { + .name = "AppArmor", + .enabled = apparmor_enabled, +@@ -1193,6 +1203,10 @@ static struct lsm_drv apparmor_drv = { + .process_label_set = apparmor_process_label_set, + .prepare = apparmor_prepare, + .cleanup = apparmor_cleanup, ++#ifdef HAVE_ISULAD ++ .file_label_set = apparmor_file_label_set, ++ .relabel = apparmor_relabel, ++#endif + }; + + struct lsm_drv *lsm_apparmor_drv_init(void) +diff --git a/src/lxc/lsm/nop.c b/src/lxc/lsm/nop.c +index 5b345b9a..188945d5 100644 +--- a/src/lxc/lsm/nop.c ++++ b/src/lxc/lsm/nop.c +@@ -24,11 +24,25 @@ static int nop_enabled(void) + return 0; + } + ++#ifdef HAVE_ISULAD ++static int nop_file_label_set(const char *path, const char *label) { ++ return 0; ++} ++ ++static int nop_relabel(const char *path, const char *label, bool shared) { ++ return 0; ++} ++#endif ++ + static struct lsm_drv nop_drv = { + .name = "nop", + .enabled = nop_enabled, + .process_label_get = nop_process_label_get, + .process_label_set = nop_process_label_set, ++#ifdef HAVE_ISULAD ++ .file_label_set = nop_file_label_set, ++ .relabel = nop_relabel, ++#endif + }; + + struct lsm_drv *lsm_nop_drv_init(void) +diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c +index 5bc9843e..864b16be 100644 +--- a/src/lxc/lsm/selinux.c ++++ b/src/lxc/lsm/selinux.c +@@ -106,6 +106,10 @@ static int selinux_file_label_set(const char *path, const char *label) + return 0; + } + ++ if (!is_selinux_enabled()) { ++ return 0; ++ } ++ + ret = lsetfilecon(path, label); + if (ret != 0) { + SYSERROR("Failed to setSELinux context to \"%s\": %s", label, path); +@@ -125,16 +129,16 @@ static int selinux_file_label_set(const char *path, const char *label) + */ + static bool is_exclude_relabel_path(const char *path) + { +- const char *exclude_path[] = { "/", "/usr", "/etc", "/tmp", "/home", "/run", "/var", "/root" }; +- size_t i; ++ const char *exclude_path[] = { "/", "/usr", "/etc", "/tmp", "/home", "/run", "/var", "/root" }; ++ size_t i; + +- for (i = 0; i < sizeof(exclude_path) / sizeof(char *); i++) { +- if (strcmp(path, exclude_path[i]) == 0) { +- return true; +- } +- } ++ for (i = 0; i < sizeof(exclude_path) / sizeof(char *); i++) { ++ if (strcmp(path, exclude_path[i]) == 0) { ++ return true; ++ } ++ } + +- return false; ++ return false; + } + + /* +@@ -146,19 +150,19 @@ static bool is_exclude_relabel_path(const char *path) + */ + static int bad_prefix(const char *fpath) + { +- const char *bad_prefixes = "/usr"; ++ const char *bad_prefixes = "/usr"; + +- if (fpath == NULL) { +- ERROR("Empty file path"); +- return -1; +- } ++ if (fpath == NULL) { ++ ERROR("Empty file path"); ++ return -1; ++ } + +- if (strncmp(fpath, bad_prefixes, strlen(bad_prefixes)) == 0) { +- ERROR("relabeling content in %s is not allowed", bad_prefixes); +- return -1; +- } ++ if (strncmp(fpath, bad_prefixes, strlen(bad_prefixes)) == 0) { ++ ERROR("relabeling content in %s is not allowed", bad_prefixes); ++ return -1; ++ } + +- return 0; ++ return 0; + } + + /* +@@ -171,51 +175,51 @@ static int bad_prefix(const char *fpath) + */ + static int recurse_set_file_label(const char *basePath, const char *label) + { +- int ret = 0; +- DIR *dir = NULL; +- struct dirent *ptr = NULL; +- char base[PATH_MAX] = { 0 }; +- +- if ((dir = opendir(basePath)) == NULL) { +- ERROR("Failed to Open dir: %s", basePath); +- return -1; +- } +- +- ret = lsetfilecon(basePath, label); +- if (ret != 0) { +- ERROR("Failed to set file label"); +- goto out; +- } +- +- while ((ptr = readdir(dir)) != NULL) { +- if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { +- continue; +- } else { +- int nret = snprintf(base, sizeof(base), "%s/%s", basePath, ptr->d_name); +- if (nret < 0 || nret >= sizeof(base)) { +- ERROR("Failed to get path"); +- ret = -1; +- goto out; +- } +- if (ptr->d_type == DT_DIR) { +- ret = recurse_set_file_label(base, label); +- if (ret != 0) { +- ERROR("Failed to set dir label"); +- goto out; +- } +- } else { +- ret = lsetfilecon(base, label); +- if (ret != 0) { +- ERROR("Failed to set file label"); +- goto out; +- } +- } +- } +- } ++ int ret = 0; ++ DIR *dir = NULL; ++ struct dirent *ptr = NULL; ++ char base[PATH_MAX] = { 0 }; ++ ++ if ((dir = opendir(basePath)) == NULL) { ++ ERROR("Failed to Open dir: %s", basePath); ++ return -1; ++ } ++ ++ ret = lsetfilecon(basePath, label); ++ if (ret != 0) { ++ ERROR("Failed to set file label"); ++ goto out; ++ } ++ ++ while ((ptr = readdir(dir)) != NULL) { ++ if (strcmp(ptr->d_name, ".") == 0 || strcmp(ptr->d_name, "..") == 0) { ++ continue; ++ } else { ++ int nret = snprintf(base, sizeof(base), "%s/%s", basePath, ptr->d_name); ++ if (nret < 0 || nret >= sizeof(base)) { ++ ERROR("Failed to get path"); ++ ret = -1; ++ goto out; ++ } ++ if (ptr->d_type == DT_DIR) { ++ ret = recurse_set_file_label(base, label); ++ if (ret != 0) { ++ ERROR("Failed to set dir label"); ++ goto out; ++ } ++ } else { ++ ret = lsetfilecon(base, label); ++ if (ret != 0) { ++ ERROR("Failed to set file label"); ++ goto out; ++ } ++ } ++ } ++ } + + out: +- closedir(dir); +- return ret; ++ closedir(dir); ++ return ret; + } + + /* +@@ -231,33 +235,33 @@ out: + */ + static int selinux_chcon(const char *fpath, const char *label, bool recurse) + { +- struct stat s_buf; +- +- if (fpath == NULL) { +- ERROR("Empty file path"); +- return -1; +- } +- +- if (label == NULL) { +- return 0; +- } +- +- if (bad_prefix(fpath) != 0) { +- return -1; +- } +- if (stat(fpath, &s_buf) != 0) { +- return -1; +- } +- if (recurse && S_ISDIR(s_buf.st_mode)) { +- return recurse_set_file_label(fpath, label); +- } +- +- if (lsetfilecon(fpath, label) != 0) { +- ERROR("Failed to set file label"); +- return -1; +- } +- +- return 0; ++ struct stat s_buf; ++ ++ if (fpath == NULL) { ++ ERROR("Empty file path"); ++ return -1; ++ } ++ ++ if (label == NULL) { ++ return 0; ++ } ++ ++ if (bad_prefix(fpath) != 0) { ++ return -1; ++ } ++ if (stat(fpath, &s_buf) != 0) { ++ return -1; ++ } ++ if (recurse && S_ISDIR(s_buf.st_mode)) { ++ return recurse_set_file_label(fpath, label); ++ } ++ ++ if (lsetfilecon(fpath, label) != 0) { ++ ERROR("Failed to set file label"); ++ return -1; ++ } ++ ++ return 0; + } + + /* +@@ -273,37 +277,41 @@ static int selinux_chcon(const char *fpath, const char *label, bool recurse) + */ + static int selinux_relabel(const char *path, const char *label, bool shared) + { +- int ret = 0; +- char *tmp_file_label = NULL; +- +- if (label == NULL) { +- return 0; +- } +- +- tmp_file_label = strdup(label); +- if (is_exclude_relabel_path(path)) { +- ERROR("SELinux relabeling of %s is not allowed", path); +- ret = -1; +- goto out; +- } +- +- if (shared) { +- context_t c = context_new(label); +- context_range_set(c, "s0"); +- free(tmp_file_label); +- tmp_file_label = strdup(context_str(c)); +- context_free(c); +- } +- +- if (selinux_chcon(path, tmp_file_label, true) != 0) { +- ERROR("Failed to modify %s's selinux context: %s", path, tmp_file_label); +- ret = -1; +- goto out; +- } ++ int ret = 0; ++ char *tmp_file_label = NULL; ++ ++ if (label == NULL) { ++ return 0; ++ } ++ ++ if (!is_selinux_enabled()) { ++ return 0; ++ } ++ ++ tmp_file_label = strdup(label); ++ if (is_exclude_relabel_path(path)) { ++ ERROR("SELinux relabeling of %s is not allowed", path); ++ ret = -1; ++ goto out; ++ } ++ ++ if (shared) { ++ context_t c = context_new(label); ++ context_range_set(c, "s0"); ++ free(tmp_file_label); ++ tmp_file_label = strdup(context_str(c)); ++ context_free(c); ++ } ++ ++ if (selinux_chcon(path, tmp_file_label, true) != 0) { ++ ERROR("Failed to modify %s's selinux context: %s", path, tmp_file_label); ++ ret = -1; ++ goto out; ++ } + + out: +- free(tmp_file_label); +- return ret; ++ free(tmp_file_label); ++ return ret; + } + + #endif +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 032176b1..5ec6117f 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -1126,6 +1126,34 @@ static int receive_mount_options(const char *data, const char *mount_label, + + return format_mount_label(data, mount_label, mnt_opts); + } ++ ++static int relabel_bind_mount_source(const char *src, const char *fstype, const char *data, const char *mount_label) ++{ ++ __do_free_string_list char **parts = NULL; ++ ssize_t parts_len; ++ ssize_t i; ++ ++ if (data == NULL) { ++ return lsm_relabel(src, mount_label, false); ++ } ++ ++ parts = lxc_string_split(data, ','); ++ if (parts == NULL) { ++ return -1; ++ } ++ ++ parts_len = lxc_array_len((void **)parts); ++ for (i = 0; i < parts_len; i++) { ++ if (strcmp(parts[i], "z") == 0) { ++ return lsm_relabel(src, mount_label, true); ++ } else if (strcmp(parts[i], "Z") == 0) { ++ return lsm_relabel(src, mount_label, false); ++ } ++ } ++ ++ return lsm_relabel(src, mount_label, false); ++} ++ + #endif + + /* +@@ -1227,7 +1255,7 @@ int safe_mount(const char *src, const char *dest, const char *fstype, + return -EINVAL; + } + +- if (strcmp(fstype, "bind") == 0 && lsm_relabel(src, mount_label, false) != 0) { ++ if (strcmp(fstype, "bind") == 0 && relabel_bind_mount_source(src, fstype, (const char *)data, mount_label) != 0) { + ERROR("Failed to reabel %s with %s", src, mount_label); + return -EINVAL; + } +-- +2.25.1 + diff --git a/0004-Removes-the-definition-of-the-thread-attributes-obje.patch b/0004-Removes-the-definition-of-the-thread-attributes-obje.patch new file mode 100644 index 0000000000000000000000000000000000000000..f154ab3519b2eebc064399dc2c5b6848b259d175 --- /dev/null +++ b/0004-Removes-the-definition-of-the-thread-attributes-obje.patch @@ -0,0 +1,162 @@ +From b1ef723b4f437aad3c0c0497174bc7d3444426cd Mon Sep 17 00:00:00 2001 +From: wujing +Date: Mon, 20 Jul 2020 15:30:42 +0800 +Subject: [PATCH 4/5] Removes the definition of the thread attributes object + +Signed-off-by: wujing +--- + src/lxc/attach.c | 1 + + src/lxc/conf.c | 1 + + src/lxc/lsm/selinux.c | 33 +++++++++++---------------------- + src/lxc/start.c | 1 + + 4 files changed, 14 insertions(+), 22 deletions(-) + +diff --git a/src/lxc/attach.c b/src/lxc/attach.c +index 068cc5f8..b33ff632 100644 +--- a/src/lxc/attach.c ++++ b/src/lxc/attach.c +@@ -1188,6 +1188,7 @@ static int create_attach_timeout_thread(int64_t attach_timeout, pid_t pid) + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ret = pthread_create(&ptid, &attr, wait_attach_timeout, timeout_conf); ++ pthread_attr_destroy(&attr); + if (ret != 0) { + ERROR("Create attach wait timeout thread failed"); + free(timeout_conf); +diff --git a/src/lxc/conf.c b/src/lxc/conf.c +index 7e4af0a9..6a25b96a 100644 +--- a/src/lxc/conf.c ++++ b/src/lxc/conf.c +@@ -4660,6 +4660,7 @@ static int run_ocihook_buffer(struct oci_hook_conf *oconf, const char *inmsg) + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + err = pthread_create(&ptid, &attr, wait_ocihook_timeout, conf); ++ pthread_attr_destroy(&attr); + if (err != 0) { + ERROR("Create wait timeout thread failed"); + free(conf); +diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c +index 864b16be..ceac0889 100644 +--- a/src/lxc/lsm/selinux.c ++++ b/src/lxc/lsm/selinux.c +@@ -100,8 +100,6 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf, + */ + static int selinux_file_label_set(const char *path, const char *label) + { +- int ret; +- + if (path == NULL || label == NULL || strcmp(label, "unconfined_t") == 0) { + return 0; + } +@@ -110,8 +108,7 @@ static int selinux_file_label_set(const char *path, const char *label) + return 0; + } + +- ret = lsetfilecon(path, label); +- if (ret != 0) { ++ if (lsetfilecon(path, label) != 0) { + SYSERROR("Failed to setSELinux context to \"%s\": %s", label, path); + return -1; + } +@@ -176,7 +173,7 @@ static int bad_prefix(const char *fpath) + static int recurse_set_file_label(const char *basePath, const char *label) + { + int ret = 0; +- DIR *dir = NULL; ++ __do_closedir DIR *dir = NULL; + struct dirent *ptr = NULL; + char base[PATH_MAX] = { 0 }; + +@@ -188,7 +185,7 @@ static int recurse_set_file_label(const char *basePath, const char *label) + ret = lsetfilecon(basePath, label); + if (ret != 0) { + ERROR("Failed to set file label"); +- goto out; ++ return ret; + } + + while ((ptr = readdir(dir)) != NULL) { +@@ -198,28 +195,25 @@ static int recurse_set_file_label(const char *basePath, const char *label) + int nret = snprintf(base, sizeof(base), "%s/%s", basePath, ptr->d_name); + if (nret < 0 || nret >= sizeof(base)) { + ERROR("Failed to get path"); +- ret = -1; +- goto out; ++ return -1; + } + if (ptr->d_type == DT_DIR) { + ret = recurse_set_file_label(base, label); + if (ret != 0) { + ERROR("Failed to set dir label"); +- goto out; ++ return ret; + } + } else { + ret = lsetfilecon(base, label); + if (ret != 0) { + ERROR("Failed to set file label"); +- goto out; ++ return ret; + } + } + } + } + +-out: +- closedir(dir); +- return ret; ++ return 0; + } + + /* +@@ -277,8 +271,7 @@ static int selinux_chcon(const char *fpath, const char *label, bool recurse) + */ + static int selinux_relabel(const char *path, const char *label, bool shared) + { +- int ret = 0; +- char *tmp_file_label = NULL; ++ __do_free char *tmp_file_label = NULL; + + if (label == NULL) { + return 0; +@@ -291,8 +284,7 @@ static int selinux_relabel(const char *path, const char *label, bool shared) + tmp_file_label = strdup(label); + if (is_exclude_relabel_path(path)) { + ERROR("SELinux relabeling of %s is not allowed", path); +- ret = -1; +- goto out; ++ return -1; + } + + if (shared) { +@@ -305,13 +297,10 @@ static int selinux_relabel(const char *path, const char *label, bool shared) + + if (selinux_chcon(path, tmp_file_label, true) != 0) { + ERROR("Failed to modify %s's selinux context: %s", path, tmp_file_label); +- ret = -1; +- goto out; ++ return -1; + } + +-out: +- free(tmp_file_label); +- return ret; ++ return 0; + } + + #endif +diff --git a/src/lxc/start.c b/src/lxc/start.c +index 51d13254..ab47420f 100644 +--- a/src/lxc/start.c ++++ b/src/lxc/start.c +@@ -2484,6 +2484,7 @@ static int create_start_timeout_thread(struct lxc_conf *conf, unsigned int start + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + ret = pthread_create(&ptid, &attr, wait_start_timeout, timeout_conf); ++ pthread_attr_destroy(&attr); + if (ret != 0) { + ERROR("Create start wait timeout thread failed"); + free(timeout_conf); +-- +2.25.1 + diff --git a/0005-solve-coredump-bug-caused-by-fstype-being-NULL-durin.patch b/0005-solve-coredump-bug-caused-by-fstype-being-NULL-durin.patch new file mode 100644 index 0000000000000000000000000000000000000000..1d2ca8d5a16b919b5f7807fb050f6291d948660f --- /dev/null +++ b/0005-solve-coredump-bug-caused-by-fstype-being-NULL-durin.patch @@ -0,0 +1,65 @@ +From 405b048dc82a8695b8a400524787243f3898cbd6 Mon Sep 17 00:00:00 2001 +From: wujing +Date: Tue, 21 Jul 2020 17:30:17 +0800 +Subject: [PATCH 5/5] solve coredump bug caused by fstype being NULL during + mount + +Signed-off-by: wujing +--- + src/lxc/lsm/selinux.c | 3 +-- + src/lxc/utils.c | 7 ++++--- + 2 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c +index ceac0889..837a3da3 100644 +--- a/src/lxc/lsm/selinux.c ++++ b/src/lxc/lsm/selinux.c +@@ -68,7 +68,6 @@ static int selinux_process_label_set(const char *inlabel, struct lxc_conf *conf, + + label = inlabel ? inlabel : conf->lsm_se_context; + if (!label) { +- + label = DEFAULT_LABEL; + } + +@@ -273,7 +272,7 @@ static int selinux_relabel(const char *path, const char *label, bool shared) + { + __do_free char *tmp_file_label = NULL; + +- if (label == NULL) { ++ if (path == NULL || label == NULL) { + return 0; + } + +diff --git a/src/lxc/utils.c b/src/lxc/utils.c +index 5ec6117f..95c00cfe 100644 +--- a/src/lxc/utils.c ++++ b/src/lxc/utils.c +@@ -1230,7 +1230,7 @@ int safe_mount(const char *src, const char *dest, const char *fstype, + + ret = mount(mntsrc, destbuf, fstype, flags, mnt_opts); + saved_errno = errno; +- if (ret < 0 && strcmp(fstype, "mqueue") == 0) { ++ if (ret < 0 && fstype != NULL && strcmp(fstype, "mqueue") == 0) { + INFO("older kernels don't support labeling of /dev/mqueue, retry without selinux context"); + ret = mount(mntsrc, destbuf, fstype, flags, data); + saved_errno = errno; +@@ -1250,12 +1250,13 @@ int safe_mount(const char *src, const char *dest, const char *fstype, + } + + #ifdef HAVE_ISULAD +- if (strcmp(fstype, "mqueue") == 0 && lsm_file_label_set(dest, mount_label) != 0) { ++ if (fstype != NULL && strcmp(fstype, "mqueue") == 0 && lsm_file_label_set(dest, mount_label) != 0) { + ERROR("Failed to set file label on %s", dest); + return -EINVAL; + } + +- if (strcmp(fstype, "bind") == 0 && relabel_bind_mount_source(src, fstype, (const char *)data, mount_label) != 0) { ++ if (fstype != NULL && strcmp(fstype, "bind") == 0 && ++ relabel_bind_mount_source(src, fstype, (const char *)data, mount_label) != 0) { + ERROR("Failed to reabel %s with %s", src, mount_label); + return -EINVAL; + } +-- +2.25.1 + diff --git a/lxc.spec b/lxc.spec index f5c0440df8b4946dbe3abd9bf4ac20fb8fd036a2..b1ce72a37afbd23757177073497d1b881969bcfc 100644 --- a/lxc.spec +++ b/lxc.spec @@ -1,5 +1,4 @@ -%global _release 2020071501 -%global debug_package %{nil} +%global _release 2020090101 Name: lxc Version: 4.0.3 @@ -7,8 +6,12 @@ Release: %{_release} Summary: Linux Containers userspace tools License: LGPLv2+ URL: https://github.com/lxc/lxc -Source0: lxc-4.0.3.tar.gz +Source0: https://linuxcontainers.org/downloads/lxc/lxc-4.0.3.tar.gz Patch9001: 0001-huawei-adapt-to-huawei-4.0.3.patch +Patch9002: 0002-add-mount-label-for-rootfs.patch +Patch9003: 0003-format-code-and-verify-mount-mode.patch +Patch9004: 0004-Removes-the-definition-of-the-thread-attributes-obje.patch +Patch9005: 0005-solve-coredump-bug-caused-by-fstype-being-NULL-durin.patch BuildRequires: systemd-units git libtool graphviz docbook2X doxygen chrpath BuildRequires: pkgconfig(libseccomp) @@ -82,24 +85,21 @@ touch %{buildroot}%{_datadir}/%{name}/__pycache__/%{name} for file in $(find %{buildroot}/usr/bin/lxc-* -type f -exec file {} ';' | grep "\" | grep -vE "*\.static" | awk -F ':' '{print $1}') do - strip --strip-debug ${file} chrpath -d ${file} done for file in $(find %{buildroot}/usr/sbin/* -type f -exec file {} ';' | grep "\" | grep -vE "*\.static" | awk -F ':' '{print $1}') do - strip --strip-debug ${file} chrpath -d ${file} done for file in $(find %{buildroot}/usr/libexec/lxc/lxc-* -type f -exec file {} ';' | grep "\" | grep -vE "*\.static" | awk -F ':' '{print $1}') do - strip --strip-debug ${file} chrpath -d ${file} done -strip --strip-debug %{buildroot}/usr/lib64/liblxc.so chrpath -d %{buildroot}/usr/lib64/liblxc.so +chmod +x %{buildroot}/usr/lib64/liblxc.so # docs mkdir -p %{buildroot}%{_pkgdocdir}/api @@ -184,6 +184,12 @@ make check %{_mandir}/*/man7/%{name}* %changelog +* Fri Sep 04 2020 zhangxiaoyu - 4.0.3-2020090101 +- Type:enhancement +- ID:NA +- SUG:NA +- DESC: add patches + * Mon Apr 20 2020 openEuler Buildteam - 4.0.3-2020071501 - Type:enhancement - ID:NA