From c0f37e083c49cfcb9441743a409fdee44d32d7c5 Mon Sep 17 00:00:00 2001
From: wujing <wujing50@huawei.com>
Date: Thu, 16 Jul 2020 16:39:35 +0800
Subject: [PATCH 03/10] format code and verify mount mode

Signed-off-by: wujing <wujing50@huawei.com>
---
 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 f251e5e7e..591d37c27 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 5b345b9a2..188945d51 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 5bc9843e4..864b16be7 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 032176b1b..5ec6117f7 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

