From 70e7dd0da58071557c897fbce2f48c8169633a54 Mon Sep 17 00:00:00 2001 From: wujing Date: Fri, 15 Apr 2022 11:11:38 +0800 Subject: [PATCH] Refactor the way to convert selinux label to shared mode Signed-off-by: wujing --- src/lxc/lsm/selinux.c | 58 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 12 deletions(-) diff --git a/src/lxc/lsm/selinux.c b/src/lxc/lsm/selinux.c index 79697c5..0a1e205 100644 --- a/src/lxc/lsm/selinux.c +++ b/src/lxc/lsm/selinux.c @@ -230,15 +230,11 @@ static int selinux_chcon(const char *fpath, const char *label, bool recurse) { struct stat s_buf; - if (fpath == NULL) { - ERROR("Empty file path"); + if (fpath == NULL || label == NULL) { + ERROR("Invalid parameters!"); return -1; } - if (label == NULL) { - return 0; - } - if (bad_prefix(fpath) != 0) { return -1; } @@ -257,6 +253,42 @@ static int selinux_chcon(const char *fpath, const char *label, bool recurse) return 0; } +/* + * convert_context_to_share_mode: set sensitivity to s0 and remove categories + * user:role:type:sensitivity[:categories] => user:role:type:s0 + * + * @label : label string + * + * Returns label with share mode on success, NULL on failure + */ +static char *convert_context_to_share_mode(const char *label) { + __do_free char *converted_label = strdup(label); + char *s = converted_label; + const char *shared_level = "s0"; + int cnt = 0; + + // selinux label format: user:role:type:sensitivity[:categories] + // locates the ":" position in front of the sensitivity + while (cnt++ < 3 && (s = strchr(s, ':')) != NULL) { + s++; + } + + // make sure sensitivity can set s0 value + if (s == NULL || strlen(s) < strlen(shared_level)) { + ERROR("Invalid selinux file context: %s", label); + return NULL; + } + + if (strcmp(s, shared_level) == 0) { + return move_ptr(converted_label); + } + + *s = '\0'; + strcat(converted_label, shared_level); + + return move_ptr(converted_label); +} + /* * selinux_relabel: Relabel changes the label of path to the filelabel string. * It changes the MCS label to s0 if shared is true. @@ -280,20 +312,22 @@ static int selinux_relabel(const char *path, const char *label, bool shared) return 0; } - tmp_file_label = strdup(label); if (is_exclude_relabel_path(path)) { ERROR("SELinux relabeling of %s is not allowed", path); return -1; } 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); + tmp_file_label = convert_context_to_share_mode(label); + if (tmp_file_label == NULL) { + ERROR("Failed to convert context to share mode: %s", label); + return -1; + } + } else { + tmp_file_label = strdup(label); } + if (selinux_chcon(path, tmp_file_label, true) != 0) { ERROR("Failed to modify %s's selinux context: %s", path, tmp_file_label); return -1; -- 2.35.1