diff --git a/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation.go b/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation.go index c9f7c39a330..a3c952f7f34 100644 --- a/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation.go +++ b/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation.go @@ -17,7 +17,7 @@ limitations under the License. package policy import ( - "strings" + "fmt" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -58,18 +58,22 @@ func CheckAllowPrivilegeEscalation() Check { } func allowPrivilegeEscalation_1_8(podMetadata *metav1.ObjectMeta, podSpec *corev1.PodSpec) CheckResult { - var forbiddenPaths []string + var badContainers []string visitContainersWithPath(podSpec, field.NewPath("spec"), func(container *corev1.Container, path *field.Path) { if container.SecurityContext == nil || container.SecurityContext.AllowPrivilegeEscalation == nil || *container.SecurityContext.AllowPrivilegeEscalation { - forbiddenPaths = append(forbiddenPaths, path.Child("securityContext", "allowPrivilegeEscalation").String()) + badContainers = append(badContainers, container.Name) } }) - if len(forbiddenPaths) > 0 { + if len(badContainers) > 0 { return CheckResult{ Allowed: false, ForbiddenReason: "allowPrivilegeEscalation != false", - ForbiddenDetail: strings.Join(forbiddenPaths, ", "), + ForbiddenDetail: fmt.Sprintf( + "%s %s must set securityContext.allowPrivilegeEscalation=false", + pluralize("container", "containers", len(badContainers)), + joinQuote(badContainers), + ), } } return CheckResult{Allowed: true} diff --git a/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation_test.go b/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation_test.go new file mode 100644 index 00000000000..bed26d28cab --- /dev/null +++ b/staging/src/k8s.io/pod-security-admission/policy/check_allowPrivilegeEscalation_test.go @@ -0,0 +1,61 @@ +/* +Copyright 2021 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package policy + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" + utilpointer "k8s.io/utils/pointer" +) + +func TestAllowPrivilegeEscalation(t *testing.T) { + tests := []struct { + name string + pod *corev1.Pod + expectReason string + expectDetail string + }{ + { + name: "multiple containers", + pod: &corev1.Pod{Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + {Name: "a"}, + {Name: "b", SecurityContext: &corev1.SecurityContext{AllowPrivilegeEscalation: nil}}, + {Name: "c", SecurityContext: &corev1.SecurityContext{AllowPrivilegeEscalation: utilpointer.Bool(true)}}, + {Name: "d", SecurityContext: &corev1.SecurityContext{AllowPrivilegeEscalation: utilpointer.Bool(false)}}, + }}}, + expectReason: `allowPrivilegeEscalation != false`, + expectDetail: `containers "a", "b", "c" must set securityContext.allowPrivilegeEscalation=false`, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + result := allowPrivilegeEscalation_1_8(&tc.pod.ObjectMeta, &tc.pod.Spec) + if result.Allowed { + t.Fatal("expected disallowed") + } + if e, a := tc.expectReason, result.ForbiddenReason; e != a { + t.Errorf("expected\n%s\ngot\n%s", e, a) + } + if e, a := tc.expectDetail, result.ForbiddenDetail; e != a { + t.Errorf("expected\n%s\ngot\n%s", e, a) + } + }) + } +} diff --git a/staging/src/k8s.io/pod-security-admission/test/fixtures_allowPrivilegeEscalation.go b/staging/src/k8s.io/pod-security-admission/test/fixtures_allowPrivilegeEscalation.go index 3cc691dfcdb..94c2494deb4 100644 --- a/staging/src/k8s.io/pod-security-admission/test/fixtures_allowPrivilegeEscalation.go +++ b/staging/src/k8s.io/pod-security-admission/test/fixtures_allowPrivilegeEscalation.go @@ -43,15 +43,14 @@ func init() { tweak(p, func(p *corev1.Pod) { p.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = pointer.BoolPtr(true) }), + // ensure initContainers are checked tweak(p, func(p *corev1.Pod) { p.Spec.InitContainers[0].SecurityContext.AllowPrivilegeEscalation = pointer.BoolPtr(true) }), // nil AllowPrivilegeEscalation tweak(p, func(p *corev1.Pod) { p.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = nil }), - tweak(p, func(p *corev1.Pod) { p.Spec.InitContainers[0].SecurityContext.AllowPrivilegeEscalation = nil }), // nil security context tweak(p, func(p *corev1.Pod) { p.Spec.Containers[0].SecurityContext = nil }), - tweak(p, func(p *corev1.Pod) { p.Spec.InitContainers[0].SecurityContext = nil }), } }, }