Promote sysctl annotations to API fields

This commit is contained in:
Jan Chaloupka
2018-05-11 15:58:29 +02:00
parent c178c7fd65
commit ab616a88b9
33 changed files with 536 additions and 838 deletions

View File

@@ -118,6 +118,9 @@ func ValidatePodSecurityPolicySpec(spec *policy.PodSecurityPolicySpec, fldPath *
allErrs = append(allErrs, validatePSPDefaultAllowPrivilegeEscalation(fldPath.Child("defaultAllowPrivilegeEscalation"), spec.DefaultAllowPrivilegeEscalation, spec.AllowPrivilegeEscalation)...)
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)...)
allErrs = append(allErrs, validatePodSecurityPolicySysctls(fldPath.Child("forbiddenSysctls"), spec.ForbiddenSysctls)...)
allErrs = append(allErrs, validatePodSecurityPolicySysctlListsDoNotOverlap(fldPath.Child("allowedUnsafeSysctls"), fldPath.Child("forbiddenSysctls"), spec.AllowedUnsafeSysctls, spec.ForbiddenSysctls)...)
return allErrs
}
@@ -138,15 +141,6 @@ func ValidatePodSecurityPolicySpecificAnnotations(annotations map[string]string,
}
}
sysctlAnnotation := annotations[policy.SysctlsPodSecurityPolicyAnnotationKey]
sysctlFldPath := fldPath.Key(policy.SysctlsPodSecurityPolicyAnnotationKey)
sysctls, err := policy.SysctlsFromPodSecurityPolicyAnnotation(sysctlAnnotation)
if err != nil {
allErrs = append(allErrs, field.Invalid(sysctlFldPath, sysctlAnnotation, err.Error()))
} else {
allErrs = append(allErrs, validatePodSecurityPolicySysctls(sysctlFldPath, sysctls)...)
}
if p := annotations[seccomp.DefaultProfileAnnotationKey]; p != "" {
allErrs = append(allErrs, apivalidation.ValidateSeccompProfile(p, fldPath.Key(seccomp.DefaultProfileAnnotationKey))...)
}
@@ -307,11 +301,55 @@ func IsValidSysctlPattern(name string) bool {
return sysctlPatternRegexp.MatchString(name)
}
func validatePodSecurityPolicySysctlListsDoNotOverlap(allowedSysctlsFldPath, forbiddenSysctlsFldPath *field.Path, allowedUnsafeSysctls, forbiddenSysctls []string) field.ErrorList {
allErrs := field.ErrorList{}
for i, allowedSysctl := range allowedUnsafeSysctls {
isAllowedSysctlPattern := false
allowedSysctlPrefix := ""
if strings.HasSuffix(allowedSysctl, "*") {
isAllowedSysctlPattern = true
allowedSysctlPrefix = strings.TrimSuffix(allowedSysctl, "*")
}
for j, forbiddenSysctl := range forbiddenSysctls {
isForbiddenSysctlPattern := false
forbiddenSysctlPrefix := ""
if strings.HasSuffix(forbiddenSysctl, "*") {
isForbiddenSysctlPattern = true
forbiddenSysctlPrefix = strings.TrimSuffix(forbiddenSysctl, "*")
}
switch {
case isAllowedSysctlPattern && isForbiddenSysctlPattern:
if strings.HasPrefix(allowedSysctlPrefix, forbiddenSysctlPrefix) {
allErrs = append(allErrs, field.Invalid(allowedSysctlsFldPath.Index(i), allowedUnsafeSysctls[i], fmt.Sprintf("sysctl overlaps with %v", forbiddenSysctl)))
} else if strings.HasPrefix(forbiddenSysctlPrefix, allowedSysctlPrefix) {
allErrs = append(allErrs, field.Invalid(forbiddenSysctlsFldPath.Index(j), forbiddenSysctls[j], fmt.Sprintf("sysctl overlaps with %v", allowedSysctl)))
}
case isAllowedSysctlPattern:
if strings.HasPrefix(forbiddenSysctl, allowedSysctlPrefix) {
allErrs = append(allErrs, field.Invalid(forbiddenSysctlsFldPath.Index(j), forbiddenSysctls[j], fmt.Sprintf("sysctl overlaps with %v", allowedSysctl)))
}
case isForbiddenSysctlPattern:
if strings.HasPrefix(allowedSysctl, forbiddenSysctlPrefix) {
allErrs = append(allErrs, field.Invalid(allowedSysctlsFldPath.Index(i), allowedUnsafeSysctls[i], fmt.Sprintf("sysctl overlaps with %v", forbiddenSysctl)))
}
default:
if allowedSysctl == forbiddenSysctl {
allErrs = append(allErrs, field.Invalid(allowedSysctlsFldPath.Index(i), allowedUnsafeSysctls[i], fmt.Sprintf("sysctl overlaps with %v", forbiddenSysctl)))
}
}
}
}
return allErrs
}
// validatePodSecurityPolicySysctls validates the sysctls fields of PodSecurityPolicy.
func validatePodSecurityPolicySysctls(fldPath *field.Path, sysctls []string) field.ErrorList {
allErrs := field.ErrorList{}
coversAll := false
for i, s := range sysctls {
if !IsValidSysctlPattern(string(s)) {
if len(s) == 0 {
allErrs = append(allErrs, field.Invalid(fldPath.Index(i), sysctls[i], fmt.Sprintf("empty sysctl not allowed")))
} else if !IsValidSysctlPattern(string(s)) {
allErrs = append(
allErrs,
field.Invalid(fldPath.Index(i), sysctls[i], fmt.Sprintf("must have at most %d characters and match regex %s",
@@ -319,9 +357,15 @@ func validatePodSecurityPolicySysctls(fldPath *field.Path, sysctls []string) fie
SysctlPatternFmt,
)),
)
} else if s[0] == '*' {
coversAll = true
}
}
if coversAll && len(sysctls) > 1 {
allErrs = append(allErrs, field.Forbidden(fldPath.Child("items"), fmt.Sprintf("if '*' is present, must not specify other sysctls")))
}
return allErrs
}