PSA: allow container_engine_t selinux type
container_engine_t (a68865582e/container_contexts (L6))
is a type that is tuned to allow running container engines (podman/docker) inside of a container. Since it's among the recognized process types as
container_t, container_kvm_t, container_init_t, it should be recognized in the security standard as well
Signed-off-by: Peter Hunt <pehunt@redhat.com>
This commit is contained in:
@@ -64,17 +64,30 @@ func CheckSELinuxOptions() Check {
|
|||||||
Versions: []VersionedCheck{
|
Versions: []VersionedCheck{
|
||||||
{
|
{
|
||||||
MinimumVersion: api.MajorMinorVersion(1, 0),
|
MinimumVersion: api.MajorMinorVersion(1, 0),
|
||||||
CheckPod: seLinuxOptions_1_0,
|
CheckPod: seLinuxOptions1_0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MinimumVersion: api.MajorMinorVersion(1, 31),
|
||||||
|
CheckPod: seLinuxOptions1_31,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
selinux_allowed_types_1_0 = sets.NewString("", "container_t", "container_init_t", "container_kvm_t")
|
selinuxAllowedTypes1_0 = sets.New("", "container_t", "container_init_t", "container_kvm_t")
|
||||||
|
selinuxAllowedTypes1_31 = sets.New("", "container_t", "container_init_t", "container_kvm_t", "container_engine_t")
|
||||||
)
|
)
|
||||||
|
|
||||||
func seLinuxOptions_1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
|
func seLinuxOptions1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
|
||||||
|
return seLinuxOptions(podMetadata, podSpec, selinuxAllowedTypes1_0)
|
||||||
|
}
|
||||||
|
|
||||||
|
func seLinuxOptions1_31(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult {
|
||||||
|
return seLinuxOptions(podMetadata, podSpec, selinuxAllowedTypes1_31)
|
||||||
|
}
|
||||||
|
|
||||||
|
func seLinuxOptions(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec, allowedTypes sets.Set[string]) CheckResult {
|
||||||
var (
|
var (
|
||||||
// sources that set bad seLinuxOptions
|
// sources that set bad seLinuxOptions
|
||||||
badSetters []string
|
badSetters []string
|
||||||
@@ -89,7 +102,7 @@ func seLinuxOptions_1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec)
|
|||||||
|
|
||||||
validSELinuxOptions := func(opts *corev1.SELinuxOptions) bool {
|
validSELinuxOptions := func(opts *corev1.SELinuxOptions) bool {
|
||||||
valid := true
|
valid := true
|
||||||
if !selinux_allowed_types_1_0.Has(opts.Type) {
|
if !allowedTypes.Has(opts.Type) {
|
||||||
valid = false
|
valid = false
|
||||||
badTypes.Insert(opts.Type)
|
badTypes.Insert(opts.Type)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,18 +50,21 @@ func TestSELinuxOptions(t *testing.T) {
|
|||||||
Type: "container_kvm_t",
|
Type: "container_kvm_t",
|
||||||
}}},
|
}}},
|
||||||
{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
Type: "bar",
|
Type: "container_engine_t",
|
||||||
}}},
|
}}},
|
||||||
{Name: "e", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "e", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
User: "bar",
|
Type: "bar",
|
||||||
}}},
|
}}},
|
||||||
{Name: "f", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "f", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
|
User: "bar",
|
||||||
|
}}},
|
||||||
|
{Name: "g", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
Role: "baz",
|
Role: "baz",
|
||||||
}}},
|
}}},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
expectReason: `seLinuxOptions`,
|
expectReason: `seLinuxOptions`,
|
||||||
expectDetail: `pod and containers "d", "e", "f" set forbidden securityContext.seLinuxOptions: types "bar", "foo"; user may not be set; role may not be set`,
|
expectDetail: `pod and containers "e", "f", "g" set forbidden securityContext.seLinuxOptions: types "bar", "foo"; user may not be set; role may not be set`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "invalid pod",
|
name: "invalid pod",
|
||||||
@@ -83,6 +86,9 @@ func TestSELinuxOptions(t *testing.T) {
|
|||||||
{Name: "c", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "c", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
Type: "container_kvm_t",
|
Type: "container_kvm_t",
|
||||||
}}},
|
}}},
|
||||||
|
{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
|
Type: "container_engine_t",
|
||||||
|
}}},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
expectReason: `seLinuxOptions`,
|
expectReason: `seLinuxOptions`,
|
||||||
@@ -105,18 +111,21 @@ func TestSELinuxOptions(t *testing.T) {
|
|||||||
Type: "container_kvm_t",
|
Type: "container_kvm_t",
|
||||||
}}},
|
}}},
|
||||||
{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
Type: "bar",
|
Type: "container_engine_t",
|
||||||
}}},
|
}}},
|
||||||
{Name: "e", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "e", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
User: "bar",
|
Type: "bar",
|
||||||
}}},
|
}}},
|
||||||
{Name: "f", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
{Name: "f", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
|
User: "bar",
|
||||||
|
}}},
|
||||||
|
{Name: "g", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
|
||||||
Role: "baz",
|
Role: "baz",
|
||||||
}}},
|
}}},
|
||||||
},
|
},
|
||||||
}},
|
}},
|
||||||
expectReason: `seLinuxOptions`,
|
expectReason: `seLinuxOptions`,
|
||||||
expectDetail: `containers "d", "e", "f" set forbidden securityContext.seLinuxOptions: type "bar"; user may not be set; role may not be set`,
|
expectDetail: `containers "e", "f", "g" set forbidden securityContext.seLinuxOptions: type "bar"; user may not be set; role may not be set`,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "bad type",
|
name: "bad type",
|
||||||
@@ -158,7 +167,7 @@ func TestSELinuxOptions(t *testing.T) {
|
|||||||
|
|
||||||
for _, tc := range tests {
|
for _, tc := range tests {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
result := seLinuxOptions_1_0(&tc.pod.ObjectMeta, &tc.pod.Spec)
|
result := seLinuxOptions1_31(&tc.pod.ObjectMeta, &tc.pod.Spec)
|
||||||
if result.Allowed {
|
if result.Allowed {
|
||||||
t.Fatal("expected disallowed")
|
t.Fatal("expected disallowed")
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user