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