diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index 7f8535a204b..7d0d076a66e 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -5234,8 +5234,8 @@ func ValidateSecurityContext(sc *core.SecurityContext, fldPath *field.Path) fiel } if sc.ProcMount != nil { - if err := IsValidProcMount(*sc.ProcMount); err != nil { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("procMount"), *sc.ProcMount, []string{string(core.DefaultProcMount), string(core.UnmaskedProcMount)})) + if err := ValidateProcMountType(fldPath.Child("procMount"), *sc.ProcMount); err != nil { + allErrs = append(allErrs, err) } } @@ -5336,13 +5336,12 @@ func IsDecremented(update, old *int32) bool { return *update < *old } -// IsValidProcMount tests that the argument is a valid ProcMountType. -func IsValidProcMount(procMountType core.ProcMountType) error { +// ValidateProcMountType tests that the argument is a valid ProcMountType. +func ValidateProcMountType(fldPath *field.Path, procMountType core.ProcMountType) *field.Error { switch procMountType { - case core.DefaultProcMount: - case core.UnmaskedProcMount: + case core.DefaultProcMount, core.UnmaskedProcMount: + return nil default: - return fmt.Errorf("unsupported ProcMount type %s", procMountType) + return field.NotSupported(fldPath, procMountType, []string{string(core.DefaultProcMount), string(core.UnmaskedProcMount)}) } - return nil } diff --git a/pkg/apis/policy/validation/validation.go b/pkg/apis/policy/validation/validation.go index fa1af17afa7..18108e2e526 100644 --- a/pkg/apis/policy/validation/validation.go +++ b/pkg/apis/policy/validation/validation.go @@ -121,6 +121,7 @@ func ValidatePodSecurityPolicySpec(spec *policy.PodSecurityPolicySpec, fldPath * allErrs = append(allErrs, validatePSPCapsAgainstDrops(spec.RequiredDropCapabilities, spec.DefaultAddCapabilities, field.NewPath("defaultAddCapabilities"))...) allErrs = append(allErrs, validatePSPCapsAgainstDrops(spec.RequiredDropCapabilities, spec.AllowedCapabilities, field.NewPath("allowedCapabilities"))...) allErrs = append(allErrs, validatePSPDefaultAllowPrivilegeEscalation(fldPath.Child("defaultAllowPrivilegeEscalation"), spec.DefaultAllowPrivilegeEscalation, spec.AllowPrivilegeEscalation)...) + allErrs = append(allErrs, validatePSPAllowedProcMountTypes(fldPath.Child("allowedProcMountTypes"), spec.AllowedProcMountTypes)...) allErrs = append(allErrs, validatePSPAllowedHostPaths(fldPath.Child("allowedHostPaths"), spec.AllowedHostPaths)...) allErrs = append(allErrs, validatePSPAllowedFlexVolumes(fldPath.Child("allowedFlexVolumes"), spec.AllowedFlexVolumes)...) allErrs = append(allErrs, validatePodSecurityPolicySysctls(fldPath.Child("allowedUnsafeSysctls"), spec.AllowedUnsafeSysctls)...) @@ -328,6 +329,17 @@ func validatePSPDefaultAllowPrivilegeEscalation(fldPath *field.Path, defaultAllo return allErrs } +// validatePSPAllowedProcMountTypes validates the DefaultAllowPrivilegeEscalation field against the AllowPrivilegeEscalation field of a PodSecurityPolicy. +func validatePSPAllowedProcMountTypes(fldPath *field.Path, allowedProcMountTypes []core.ProcMountType) field.ErrorList { + allErrs := field.ErrorList{} + for i, procMountType := range allowedProcMountTypes { + if err := apivalidation.ValidateProcMountType(fldPath.Index(i), procMountType); err != nil { + allErrs = append(allErrs, err) + } + } + return allErrs +} + const sysctlPatternSegmentFmt string = "([a-z0-9][-_a-z0-9]*)?[a-z0-9*]" const SysctlPatternFmt string = "(" + apivalidation.SysctlSegmentFmt + "\\.)*" + sysctlPatternSegmentFmt diff --git a/pkg/apis/policy/validation/validation_test.go b/pkg/apis/policy/validation/validation_test.go index fea5d01fad9..aecd163afd5 100644 --- a/pkg/apis/policy/validation/validation_test.go +++ b/pkg/apis/policy/validation/validation_test.go @@ -384,6 +384,9 @@ func TestValidatePodSecurityPolicy(t *testing.T) { nonEmptyFlexVolumes := validPSP() nonEmptyFlexVolumes.Spec.AllowedFlexVolumes = []policy.AllowedFlexVolume{{Driver: "example/driver"}} + invalidProcMount := validPSP() + invalidProcMount.Spec.AllowedProcMountTypes = []api.ProcMountType{api.ProcMountType("bogus")} + type testCase struct { psp *policy.PodSecurityPolicy errorType field.ErrorType @@ -550,6 +553,11 @@ func TestValidatePodSecurityPolicy(t *testing.T) { errorType: field.ErrorTypeRequired, errorDetail: "must specify a driver", }, + "invalid allowedProcMountTypes": { + psp: invalidProcMount, + errorType: field.ErrorTypeNotSupported, + errorDetail: `supported values: "Default", "Unmasked"`, + }, } for k, v := range errorCases { @@ -643,6 +651,10 @@ func TestValidatePodSecurityPolicy(t *testing.T) { flexvolumeWhenAllVolumesAllowed.Spec.AllowedFlexVolumes = []policy.AllowedFlexVolume{ {Driver: "example/driver2"}, } + + validProcMount := validPSP() + validProcMount.Spec.AllowedProcMountTypes = []api.ProcMountType{api.DefaultProcMount, api.UnmaskedProcMount} + successCases := map[string]struct { psp *policy.PodSecurityPolicy }{ @@ -682,6 +694,9 @@ func TestValidatePodSecurityPolicy(t *testing.T) { "allow white-listed flexVolume when all volumes are allowed": { psp: flexvolumeWhenAllVolumesAllowed, }, + "valid allowedProcMountTypes": { + psp: validProcMount, + }, } for k, v := range successCases {