1215 lines
40 KiB
Diff
1215 lines
40 KiB
Diff
From 0b8bc902c0c7acb54efb1fd4be5121dbf9a08598 Mon Sep 17 00:00:00 2001
|
|
From: wujing <wujing50@huawei.com>
|
|
Date: Wed, 15 Jul 2020 16:09:35 +0800
|
|
Subject: [PATCH 02/10] add mount label for rootfs
|
|
|
|
Signed-off-by: wujing <wujing50@huawei.com>
|
|
---
|
|
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 4a0961f13..1ff3d9812 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 0744c19b3..7e4af0a95 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/<ttydir>/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/<ttydir>/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 4b6409e3e..c9265b65e 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 b1d101a9d..f108b37b4 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 553e0c99a..2f87dd68d 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 ee578bb03..4872f5598 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 dba0ab584..5bc9843e4 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 <selinux/context.h>
|
|
+#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 4e418fbb9..032176b1b 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/<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 39ef5792f..4d1c49bab 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
|
|
|