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{
 | 
			
		||||
			{
 | 
			
		||||
				MinimumVersion: api.MajorMinorVersion(1, 0),
 | 
			
		||||
				CheckPod:       seLinuxOptions_1_0,
 | 
			
		||||
				CheckPod:       seLinuxOptions1_0,
 | 
			
		||||
			},
 | 
			
		||||
			{
 | 
			
		||||
				MinimumVersion: api.MajorMinorVersion(1, 31),
 | 
			
		||||
				CheckPod:       seLinuxOptions1_31,
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 (
 | 
			
		||||
		// sources that set bad seLinuxOptions
 | 
			
		||||
		badSetters []string
 | 
			
		||||
@@ -89,7 +102,7 @@ func seLinuxOptions_1_0(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec)
 | 
			
		||||
 | 
			
		||||
	validSELinuxOptions := func(opts *corev1.SELinuxOptions) bool {
 | 
			
		||||
		valid := true
 | 
			
		||||
		if !selinux_allowed_types_1_0.Has(opts.Type) {
 | 
			
		||||
		if !allowedTypes.Has(opts.Type) {
 | 
			
		||||
			valid = false
 | 
			
		||||
			badTypes.Insert(opts.Type)
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -50,18 +50,21 @@ func TestSELinuxOptions(t *testing.T) {
 | 
			
		||||
						Type: "container_kvm_t",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						Type: "bar",
 | 
			
		||||
						Type: "container_engine_t",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "e", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						User: "bar",
 | 
			
		||||
						Type: "bar",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "f", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						User: "bar",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "g", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						Role: "baz",
 | 
			
		||||
					}}},
 | 
			
		||||
				},
 | 
			
		||||
			}},
 | 
			
		||||
			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",
 | 
			
		||||
@@ -83,6 +86,9 @@ func TestSELinuxOptions(t *testing.T) {
 | 
			
		||||
					{Name: "c", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						Type: "container_kvm_t",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						Type: "container_engine_t",
 | 
			
		||||
					}}},
 | 
			
		||||
				},
 | 
			
		||||
			}},
 | 
			
		||||
			expectReason: `seLinuxOptions`,
 | 
			
		||||
@@ -105,18 +111,21 @@ func TestSELinuxOptions(t *testing.T) {
 | 
			
		||||
						Type: "container_kvm_t",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "d", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						Type: "bar",
 | 
			
		||||
						Type: "container_engine_t",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "e", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						User: "bar",
 | 
			
		||||
						Type: "bar",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "f", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						User: "bar",
 | 
			
		||||
					}}},
 | 
			
		||||
					{Name: "g", SecurityContext: &corev1.SecurityContext{SELinuxOptions: &corev1.SELinuxOptions{
 | 
			
		||||
						Role: "baz",
 | 
			
		||||
					}}},
 | 
			
		||||
				},
 | 
			
		||||
			}},
 | 
			
		||||
			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",
 | 
			
		||||
@@ -158,7 +167,7 @@ func TestSELinuxOptions(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	for _, tc := range tests {
 | 
			
		||||
		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 {
 | 
			
		||||
				t.Fatal("expected disallowed")
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user