Signed-off-by: zhangxiaoyu <zhangxiaoyu58@huawei.com> (cherry picked from commit 9c3acba9915c23718ae8a806daa49022a73756eb)
347 lines
17 KiB
Diff
347 lines
17 KiB
Diff
From d231a8e5f8ea1c8a5584fdc8baa579b18d1b6a19 Mon Sep 17 00:00:00 2001
|
|
From: zhongtao <zhongtao17@huawei.com>
|
|
Date: Wed, 29 Mar 2023 03:26:45 +0800
|
|
Subject: [PATCH 38/46] support to config selinux label in cri
|
|
|
|
Signed-off-by: zhongtao <zhongtao17@huawei.com>
|
|
---
|
|
.../cri/cri_container_manager_service_impl.cc | 47 +++++----
|
|
.../cri/cri_container_manager_service_impl.h | 1 +
|
|
src/daemon/entry/cri/cri_helpers.cc | 95 ++++++++++++++++++-
|
|
src/daemon/entry/cri/cri_helpers.h | 17 +++-
|
|
.../cri_pod_sandbox_manager_service_impl.cc | 47 ++++-----
|
|
5 files changed, 149 insertions(+), 58 deletions(-)
|
|
|
|
diff --git a/src/daemon/entry/cri/cri_container_manager_service_impl.cc b/src/daemon/entry/cri/cri_container_manager_service_impl.cc
|
|
index a64d222c..6278512f 100644
|
|
--- a/src/daemon/entry/cri/cri_container_manager_service_impl.cc
|
|
+++ b/src/daemon/entry/cri/cri_container_manager_service_impl.cc
|
|
@@ -98,30 +98,21 @@ auto ContainerManagerServiceImpl::PackCreateContainerHostConfigSecurityContext(
|
|
// security Opt Separator Change Version : k8s v1.23.0 (Corresponds to docker 1.11.x)
|
|
// New version '=' , old version ':', iSulad cri is based on v18.09, so iSulad cri use new version separator
|
|
const char securityOptSep { '=' };
|
|
- std::vector<std::string> securityOpts = CRIHelpers::GetSecurityOpts(
|
|
- containerConfig.linux().security_context().seccomp_profile_path(), securityOptSep, error);
|
|
+ const ::runtime::v1alpha2::LinuxContainerSecurityContext &context = containerConfig.linux().security_context();
|
|
+ CRIHelpers::commonSecurityContext commonContext = {
|
|
+ .hasSELinuxOption = context.has_selinux_options(),
|
|
+ .selinuxOption = context.selinux_options(),
|
|
+ .seccompProfile = context.seccomp_profile_path(),
|
|
+ };
|
|
+ std::vector<std::string> securityOpts = CRIHelpers::GetSecurityOpts(commonContext, securityOptSep, error);
|
|
if (error.NotEmpty()) {
|
|
- error.Errorf("failed to generate security options for container %s", containerConfig.metadata().name().c_str());
|
|
+ error.Errorf("Failed to generate security options for container %s", containerConfig.metadata().name().c_str());
|
|
return -1;
|
|
}
|
|
- if (!securityOpts.empty()) {
|
|
- char **tmp_security_opt = nullptr;
|
|
- if (securityOpts.size() > (SIZE_MAX / sizeof(char *)) - hostconfig->security_opt_len) {
|
|
- error.Errorf("Out of memory");
|
|
- return -1;
|
|
- }
|
|
- size_t newSize = (hostconfig->security_opt_len + securityOpts.size()) * sizeof(char *);
|
|
- size_t oldSize = hostconfig->security_opt_len * sizeof(char *);
|
|
- int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostconfig->security_opt, oldSize);
|
|
- if (ret != 0) {
|
|
- error.Errorf("Out of memory");
|
|
- return -1;
|
|
- }
|
|
- hostconfig->security_opt = tmp_security_opt;
|
|
- for (const auto &securityOpt : securityOpts) {
|
|
- hostconfig->security_opt[hostconfig->security_opt_len] = util_strdup_s(securityOpt.c_str());
|
|
- hostconfig->security_opt_len++;
|
|
- }
|
|
+ CRIHelpers::AddSecurityOptsToHostConfig(securityOpts, hostconfig, error);
|
|
+ if (error.NotEmpty()) {
|
|
+ error.Errorf("Failed to add securityOpts to hostconfig for container %s", containerConfig.metadata().name().c_str());
|
|
+ return -1;
|
|
}
|
|
return 0;
|
|
}
|
|
@@ -148,7 +139,7 @@ auto ContainerManagerServiceImpl::DoUsePodLevelSELinuxConfig(const runtime::v1al
|
|
}
|
|
|
|
tmp_str = std::string(inspect->process_label);
|
|
- selinuxLabelOpts = CRIHelpers::GetSELinuxLabelOpts(tmp_str, error);
|
|
+ selinuxLabelOpts = CRIHelpers::GetPodSELinuxLabelOpts(tmp_str, error);
|
|
if (error.NotEmpty()) {
|
|
ERROR("Failed to get SELinuxLabelOpts for container %s", containerConfig.metadata().name().c_str());
|
|
goto cleanup;
|
|
@@ -181,7 +172,14 @@ cleanup:
|
|
return ret;
|
|
}
|
|
|
|
-
|
|
+auto ContainerManagerServiceImpl::IsSELinuxLabelEmpty(const ::runtime::v1alpha2::SELinuxOption &selinuxOption) -> bool
|
|
+{
|
|
+ if (selinuxOption.user().length() == 0 && selinuxOption.role().length() == 0 && selinuxOption.type().length() == 0 &&
|
|
+ selinuxOption.level().length() == 0) {
|
|
+ return true;
|
|
+ }
|
|
+ return false;
|
|
+}
|
|
|
|
auto ContainerManagerServiceImpl::GenerateCreateContainerHostConfig(
|
|
const runtime::v1alpha2::ContainerConfig &containerConfig,
|
|
@@ -219,7 +217,8 @@ auto ContainerManagerServiceImpl::GenerateCreateContainerHostConfig(
|
|
|
|
// If selinux label is not specified in container config, use pod level SELinux config
|
|
if (!containerConfig.linux().has_security_context() ||
|
|
- !containerConfig.linux().security_context().has_selinux_options()) {
|
|
+ !containerConfig.linux().security_context().has_selinux_options() ||
|
|
+ IsSELinuxLabelEmpty(containerConfig.linux().security_context().selinux_options())) {
|
|
if (DoUsePodLevelSELinuxConfig(containerConfig, hostconfig, realPodSandboxID, error) != 0) {
|
|
error.SetError("Failed to security context to host config");
|
|
goto cleanup;
|
|
diff --git a/src/daemon/entry/cri/cri_container_manager_service_impl.h b/src/daemon/entry/cri/cri_container_manager_service_impl.h
|
|
index dcb2cd44..ad53a65f 100644
|
|
--- a/src/daemon/entry/cri/cri_container_manager_service_impl.h
|
|
+++ b/src/daemon/entry/cri/cri_container_manager_service_impl.h
|
|
@@ -84,6 +84,7 @@ private:
|
|
Errors &error) -> container_create_request *;
|
|
auto GenerateCreateContainerHostConfig(const runtime::v1alpha2::ContainerConfig &containerConfig,
|
|
const std::string &realPodSandboxID, Errors &error) -> host_config *;
|
|
+ auto IsSELinuxLabelEmpty(const ::runtime::v1alpha2::SELinuxOption &selinuxOption) -> bool;
|
|
auto GenerateCreateContainerCustomConfig(const std::string &containerName, const std::string &realPodSandboxID,
|
|
const runtime::v1alpha2::ContainerConfig &containerConfig,
|
|
const runtime::v1alpha2::PodSandboxConfig &podSandboxConfig,
|
|
diff --git a/src/daemon/entry/cri/cri_helpers.cc b/src/daemon/entry/cri/cri_helpers.cc
|
|
index 2bc6bed7..ec14d0b2 100644
|
|
--- a/src/daemon/entry/cri/cri_helpers.cc
|
|
+++ b/src/daemon/entry/cri/cri_helpers.cc
|
|
@@ -68,6 +68,8 @@ const std::string Constants::CNI_MUTL_NET_EXTENSION_KEY { "extension.network.kub
|
|
const std::string Constants::CNI_MUTL_NET_EXTENSION_ARGS_KEY { "CNI_MUTLINET_EXTENSION" };
|
|
const std::string Constants::CNI_ARGS_EXTENSION_PREFIX_KEY { "extension.network.kubernetes.io/cniargs/" };
|
|
const std::string Constants::IMAGE_NAME_ANNOTATION_KEY { "io.kubernetes.cri.image-name" };
|
|
+// Usually, the format of level is "s0:c60,c525" or "s0-s0:c40.c23"
|
|
+const std::string Constants::SELINUX_LABEL_LEVEL_PATTERN { "^s[0-9](-s[0-9])?(:c[0-9]{1,4}(\\.c[0-9]{1,4})?(,c[0-9]{1,4}(\\.c[0-9]{1,4})?)*)?$" };
|
|
|
|
const char *InternalLabelKeys[] = { CRIHelpers::Constants::CONTAINER_TYPE_LABEL_KEY.c_str(),
|
|
CRIHelpers::Constants::CONTAINER_LOGPATH_LABEL_KEY.c_str(),
|
|
@@ -598,6 +600,34 @@ auto GetSeccompiSuladOpts(const std::string &seccompProfile, Errors &error) -> s
|
|
return ret;
|
|
}
|
|
|
|
+
|
|
+auto GetSelinuxiSuladOpts(const ::runtime::v1alpha2::SELinuxOption &selinux, Errors &error)-> std::vector<iSuladOpt>
|
|
+{
|
|
+ std::vector<iSuladOpt> selinuxOpts { };
|
|
+ // LabeSep is consistent with the separator used when parsing labels
|
|
+ const char labeSep { ':' };
|
|
+
|
|
+ if (selinux.level().length() != 0 &&
|
|
+ util_reg_match(CRIHelpers::Constants::SELINUX_LABEL_LEVEL_PATTERN.c_str(), selinux.level().c_str()) != 0) {
|
|
+ error.Errorf("The format of 'level' %s is not correct", selinux.level().c_str());
|
|
+ return selinuxOpts;
|
|
+ }
|
|
+
|
|
+ if (selinux.user().length() > 0) {
|
|
+ selinuxOpts.push_back({ "label", std::string("user") + std::string(1, labeSep) + selinux.user(), "" });
|
|
+ }
|
|
+ if (selinux.role().length() > 0) {
|
|
+ selinuxOpts.push_back({ "label", std::string("role") + std::string(1, labeSep) + selinux.role(), "" });
|
|
+ }
|
|
+ if (selinux.type().length() > 0) {
|
|
+ selinuxOpts.push_back({ "label", std::string("type") + std::string(1, labeSep) + selinux.type(), "" });
|
|
+ }
|
|
+ if (selinux.level().length() > 0) {
|
|
+ selinuxOpts.push_back({ "label", std::string("level") + std::string(1, labeSep) + selinux.level(), "" });
|
|
+ }
|
|
+ return selinuxOpts;
|
|
+}
|
|
+
|
|
auto GetSeccompSecurityOpts(const std::string &seccompProfile, const char &separator, Errors &error)
|
|
-> std::vector<std::string>
|
|
{
|
|
@@ -609,17 +639,44 @@ auto GetSeccompSecurityOpts(const std::string &seccompProfile, const char &separ
|
|
return fmtiSuladOpts(seccompOpts, separator);
|
|
}
|
|
|
|
-auto GetSecurityOpts(const std::string &seccompProfile, const char &separator, Errors &error)
|
|
+auto GetSELinuxLabelOpts(const bool hasSELinuxOption, const ::runtime::v1alpha2::SELinuxOption &selinux,
|
|
+ const char &separator, Errors &error)
|
|
-> std::vector<std::string>
|
|
{
|
|
- std::vector<std::string> seccompSecurityOpts = GetSeccompSecurityOpts(seccompProfile, separator, error);
|
|
+ if (!hasSELinuxOption) {
|
|
+ return std::vector<std::string>();
|
|
+ }
|
|
+
|
|
+ std::vector<iSuladOpt> selinuxOpts = GetSelinuxiSuladOpts(selinux, error);
|
|
if (error.NotEmpty()) {
|
|
- error.Errorf("failed to generate seccomp security options for container: %s", error.GetMessage().c_str());
|
|
+ return std::vector<std::string>();
|
|
}
|
|
- return seccompSecurityOpts;
|
|
+
|
|
+ return fmtiSuladOpts(selinuxOpts, separator);
|
|
}
|
|
|
|
-auto GetSELinuxLabelOpts(const std::string &selinuxLabel, Errors &error)
|
|
+auto GetSecurityOpts(const commonSecurityContext &context, const char &separator, Errors &error)
|
|
+-> std::vector<std::string>
|
|
+{
|
|
+ std::vector<std::string> securityOpts;
|
|
+ std::vector<std::string> seccompSecurityOpts = GetSeccompSecurityOpts(context.seccompProfile, separator, error);
|
|
+ if (error.NotEmpty()) {
|
|
+ error.Errorf("Failed to generate seccomp security options for container: %s", error.GetMessage().c_str());
|
|
+ return securityOpts;
|
|
+ }
|
|
+
|
|
+ std::vector<std::string> selinuxOpts = CRIHelpers::GetSELinuxLabelOpts(context.hasSELinuxOption,
|
|
+ context.selinuxOption, separator, error);
|
|
+ if (error.NotEmpty()) {
|
|
+ error.Errorf("Failed to generate SELinuxLabel options for container %s", error.GetMessage().c_str());
|
|
+ return securityOpts;
|
|
+ }
|
|
+ securityOpts.insert(securityOpts.end(), seccompSecurityOpts.begin(), seccompSecurityOpts.end());
|
|
+ securityOpts.insert(securityOpts.end(), selinuxOpts.begin(), selinuxOpts.end());
|
|
+ return securityOpts;
|
|
+}
|
|
+
|
|
+auto GetPodSELinuxLabelOpts(const std::string &selinuxLabel, Errors &error)
|
|
-> std::vector<std::string>
|
|
{
|
|
// security Opt Separator Change Version : k8s v1.23.0 (Corresponds to docker 1.11.x)
|
|
@@ -650,6 +707,34 @@ auto GetSELinuxLabelOpts(const std::string &selinuxLabel, Errors &error)
|
|
return fmtiSuladOpts(selinuxOpts, securityOptSep);
|
|
}
|
|
|
|
+void AddSecurityOptsToHostConfig(std::vector<std::string> &securityOpts, host_config *hostconfig, Errors &error)
|
|
+{
|
|
+ if (securityOpts.empty()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ char **tmp_security_opt = nullptr;
|
|
+ if (securityOpts.size() > (SIZE_MAX / sizeof(char *)) - hostconfig->security_opt_len) {
|
|
+ error.Errorf("Too many securityOpts");
|
|
+ ERROR("Too many securityOpts");
|
|
+ return;
|
|
+ }
|
|
+ size_t newSize = (hostconfig->security_opt_len + securityOpts.size()) * sizeof(char *);
|
|
+ size_t oldSize = hostconfig->security_opt_len * sizeof(char *);
|
|
+ int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hostconfig->security_opt, oldSize);
|
|
+ if (ret != 0) {
|
|
+ error.Errorf("Out of memory");
|
|
+ ERROR("Out of memory");
|
|
+ return;
|
|
+ }
|
|
+ hostconfig->security_opt = tmp_security_opt;
|
|
+ for (const auto &securityOpt : securityOpts) {
|
|
+ hostconfig->security_opt[hostconfig->security_opt_len] = util_strdup_s(securityOpt.c_str());
|
|
+ hostconfig->security_opt_len++;
|
|
+ }
|
|
+
|
|
+}
|
|
+
|
|
auto CreateCheckpoint(CRI::PodSandboxCheckpoint &checkpoint, Errors &error) -> std::string
|
|
{
|
|
cri_checkpoint *criCheckpoint { nullptr };
|
|
diff --git a/src/daemon/entry/cri/cri_helpers.h b/src/daemon/entry/cri/cri_helpers.h
|
|
index 4ef227d7..a5d6cf61 100644
|
|
--- a/src/daemon/entry/cri/cri_helpers.h
|
|
+++ b/src/daemon/entry/cri/cri_helpers.h
|
|
@@ -67,10 +67,17 @@ public:
|
|
static const std::string CNI_MUTL_NET_EXTENSION_KEY;
|
|
static const std::string CNI_MUTL_NET_EXTENSION_ARGS_KEY;
|
|
static const std::string CNI_ARGS_EXTENSION_PREFIX_KEY;
|
|
+ static const std::string SELINUX_LABEL_LEVEL_PATTERN;
|
|
|
|
static const std::string IMAGE_NAME_ANNOTATION_KEY;
|
|
};
|
|
|
|
+struct commonSecurityContext {
|
|
+ const bool hasSELinuxOption;
|
|
+ const ::runtime::v1alpha2::SELinuxOption selinuxOption;
|
|
+ const std::string seccompProfile;
|
|
+};
|
|
+
|
|
auto GetDefaultSandboxImage(Errors &err) -> std::string;
|
|
|
|
auto MakeLabels(const google::protobuf::Map<std::string, std::string> &mapLabels, Errors &error)
|
|
@@ -124,12 +131,18 @@ auto ValidateCheckpointKey(const std::string &key, Errors &error) -> bool;
|
|
|
|
auto ToIsuladContainerStatus(const runtime::v1alpha2::ContainerStateValue &state) -> std::string;
|
|
|
|
-auto GetSecurityOpts(const std::string &seccompProfile, const char &separator, Errors &error)
|
|
+auto GetSELinuxLabelOpts(const bool hasSELinuxOption, const ::runtime::v1alpha2::SELinuxOption &selinux,
|
|
+ const char &separator, Errors &error)
|
|
-> std::vector<std::string>;
|
|
|
|
-auto GetSELinuxLabelOpts(const std::string &selinuxLabel, Errors &error)
|
|
+auto GetSecurityOpts(const commonSecurityContext &context, const char &separator, Errors &error)
|
|
-> std::vector<std::string>;
|
|
|
|
+auto GetPodSELinuxLabelOpts(const std::string &selinuxLabel, Errors &error)
|
|
+-> std::vector<std::string>;
|
|
+
|
|
+void AddSecurityOptsToHostConfig(std::vector<std::string> &securityOpts, host_config *hostconfig, Errors &error);
|
|
+
|
|
auto CreateCheckpoint(CRI::PodSandboxCheckpoint &checkpoint, Errors &error) -> std::string;
|
|
|
|
void GetCheckpoint(const std::string &jsonCheckPoint, CRI::PodSandboxCheckpoint &checkpoint, Errors &error);
|
|
diff --git a/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc b/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc
|
|
index 7ff545db..1cb3254d 100644
|
|
--- a/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc
|
|
+++ b/src/daemon/entry/cri/cri_pod_sandbox_manager_service_impl.cc
|
|
@@ -197,34 +197,27 @@ void PodSandboxManagerServiceImpl::MakeSandboxIsuladConfig(const runtime::v1alph
|
|
const char securityOptSep = '=';
|
|
|
|
// Security Opts
|
|
- if (c.linux().has_security_context()) {
|
|
- std::vector<std::string> securityOpts =
|
|
- CRIHelpers::GetSecurityOpts(c.linux().security_context().seccomp_profile_path(), securityOptSep, error);
|
|
- if (error.NotEmpty()) {
|
|
- error.Errorf("failed to generate security options for sandbox %s: %s",
|
|
- c.metadata().name().c_str(), error.GetMessage().c_str());
|
|
- return;
|
|
- }
|
|
- if (!securityOpts.empty()) {
|
|
- char **tmp_security_opt = nullptr;
|
|
+ if (!c.linux().has_security_context()) {
|
|
+ return;
|
|
+ }
|
|
|
|
- if (securityOpts.size() > (SIZE_MAX / sizeof(char *)) - hc->security_opt_len) {
|
|
- error.Errorf("Out of memory");
|
|
- return;
|
|
- }
|
|
- size_t newSize = (hc->security_opt_len + securityOpts.size()) * sizeof(char *);
|
|
- size_t oldSize = hc->security_opt_len * sizeof(char *);
|
|
- int ret = util_mem_realloc((void **)(&tmp_security_opt), newSize, (void *)hc->security_opt, oldSize);
|
|
- if (ret != 0) {
|
|
- error.Errorf("Out of memory");
|
|
- return;
|
|
- }
|
|
- hc->security_opt = tmp_security_opt;
|
|
- for (const auto &securityOpt : securityOpts) {
|
|
- hc->security_opt[hc->security_opt_len] = util_strdup_s(securityOpt.c_str());
|
|
- hc->security_opt_len++;
|
|
- }
|
|
- }
|
|
+ CRIHelpers::commonSecurityContext commonContext = {
|
|
+ .hasSELinuxOption = c.linux().security_context().has_selinux_options(),
|
|
+ .selinuxOption = c.linux().security_context().selinux_options(),
|
|
+ .seccompProfile = c.linux().security_context().seccomp_profile_path(),
|
|
+ };
|
|
+
|
|
+ std::vector<std::string> securityOpts = CRIHelpers::GetSecurityOpts(commonContext, securityOptSep, error);
|
|
+ if (error.NotEmpty()) {
|
|
+ error.Errorf("Failed to generate security options for sandbox %s: %s",
|
|
+ c.metadata().name().c_str(), error.GetMessage().c_str());
|
|
+ return;
|
|
+ }
|
|
+ CRIHelpers::AddSecurityOptsToHostConfig(securityOpts, hc, error);
|
|
+ if (error.NotEmpty()) {
|
|
+ error.Errorf("Failed to add securityOpts to hostconfig for sandbox %s: %s", c.metadata().name().c_str(),
|
|
+ error.GetMessage().c_str());
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
--
|
|
2.25.1
|
|
|