// sortVolumes sorts the volume slice of the SCC in place. func sortVolumes(scc *kapi.SecurityContextConstraints) { if scc.Volumes == nil || len(scc.Volumes) == 0 { return } volumes := sccutil.FSTypeToStringSet(scc.Volumes).List() sort.StringSlice(volumes).Sort() scc.Volumes = sliceToFSType(volumes) }
// Ensure a container's SecurityContext is in compliance with the given constraints func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, container *api.Container, fldPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} if container.SecurityContext == nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("securityContext"), container.SecurityContext, "No security context is set")) return allErrs } sc := container.SecurityContext allErrs = append(allErrs, s.runAsUserStrategy.Validate(pod, container)...) allErrs = append(allErrs, s.seLinuxStrategy.Validate(pod, container)...) if !s.scc.AllowPrivilegedContainer && *sc.Privileged { allErrs = append(allErrs, field.Invalid(fldPath.Child("privileged"), *sc.Privileged, "Privileged containers are not allowed")) } allErrs = append(allErrs, s.capabilitiesStrategy.Validate(pod, container)...) if len(pod.Spec.Volumes) > 0 && !sccutil.SCCAllowsAllVolumes(s.scc) { allowedVolumes := sccutil.FSTypeToStringSet(s.scc.Volumes) for i, v := range pod.Spec.Volumes { fsType, err := sccutil.GetVolumeFSType(v) if err != nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("volumes").Index(i), string(fsType), err.Error())) continue } if !allowedVolumes.Has(string(fsType)) { allErrs = append(allErrs, field.Invalid( fldPath.Child("volumes").Index(i), string(fsType), fmt.Sprintf("%s volumes are not allowed to be used", string(fsType)))) } } } if !s.scc.AllowHostNetwork && pod.Spec.SecurityContext.HostNetwork { allErrs = append(allErrs, field.Invalid(fldPath.Child("hostNetwork"), pod.Spec.SecurityContext.HostNetwork, "Host network is not allowed to be used")) } if !s.scc.AllowHostPorts { containersPath := fldPath.Child("containers") for idx, c := range pod.Spec.Containers { idxPath := containersPath.Index(idx) allErrs = append(allErrs, s.hasHostPort(&c, idxPath)...) } } if !s.scc.AllowHostPID && pod.Spec.SecurityContext.HostPID { allErrs = append(allErrs, field.Invalid(fldPath.Child("hostPID"), pod.Spec.SecurityContext.HostPID, "Host PID is not allowed to be used")) } if !s.scc.AllowHostIPC && pod.Spec.SecurityContext.HostIPC { allErrs = append(allErrs, field.Invalid(fldPath.Child("hostIPC"), pod.Spec.SecurityContext.HostIPC, "Host IPC is not allowed to be used")) } if s.scc.ReadOnlyRootFilesystem { if sc.ReadOnlyRootFilesystem == nil { allErrs = append(allErrs, field.Invalid(fldPath.Child("readOnlyRootFilesystem"), sc.ReadOnlyRootFilesystem, "ReadOnlyRootFilesystem may not be nil and must be set to true")) } else if !*sc.ReadOnlyRootFilesystem { allErrs = append(allErrs, field.Invalid(fldPath.Child("readOnlyRootFilesystem"), *sc.ReadOnlyRootFilesystem, "ReadOnlyRootFilesystem must be set to true")) } } return allErrs }