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