mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-23 10:32:03 +00:00
PodSecurityPolicy: pass effective capabilities to validation interface
This commit is contained in:
parent
abc7c077e1
commit
9e34f2b968
@ -81,17 +81,10 @@ func (s *defaultCapabilities) Generate(pod *api.Pod, container *api.Container) (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate ensures that the specified values fall within the range of the strategy.
|
// Validate ensures that the specified values fall within the range of the strategy.
|
||||||
func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container) field.ErrorList {
|
func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container, capabilities *api.Capabilities) field.ErrorList {
|
||||||
allErrs := field.ErrorList{}
|
allErrs := field.ErrorList{}
|
||||||
|
|
||||||
// if the security context isn't set then we haven't generated correctly. Shouldn't get here
|
if capabilities == nil {
|
||||||
// if using the provider correctly
|
|
||||||
if container.SecurityContext == nil {
|
|
||||||
allErrs = append(allErrs, field.Invalid(field.NewPath("securityContext"), container.SecurityContext, "no security context is set"))
|
|
||||||
return allErrs
|
|
||||||
}
|
|
||||||
|
|
||||||
if container.SecurityContext.Capabilities == nil {
|
|
||||||
// if container.SC.Caps is nil then nothing was defaulted by the strategy or requested by the pod author
|
// if container.SC.Caps is nil then nothing was defaulted by the strategy or requested by the pod author
|
||||||
// if there are no required caps on the strategy and nothing is requested on the pod
|
// if there are no required caps on the strategy and nothing is requested on the pod
|
||||||
// then we can safely return here without further validation.
|
// then we can safely return here without further validation.
|
||||||
@ -101,7 +94,7 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container) f
|
|||||||
|
|
||||||
// container has no requested caps but we have required caps. We should have something in
|
// container has no requested caps but we have required caps. We should have something in
|
||||||
// at least the drops on the container.
|
// at least the drops on the container.
|
||||||
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities"), container.SecurityContext.Capabilities,
|
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities"), capabilities,
|
||||||
"required capabilities are not set on the securityContext"))
|
"required capabilities are not set on the securityContext"))
|
||||||
return allErrs
|
return allErrs
|
||||||
}
|
}
|
||||||
@ -116,7 +109,7 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container) f
|
|||||||
// validate that anything being added is in the default or allowed sets
|
// validate that anything being added is in the default or allowed sets
|
||||||
defaultAdd := makeCapSet(s.defaultAddCapabilities)
|
defaultAdd := makeCapSet(s.defaultAddCapabilities)
|
||||||
|
|
||||||
for _, cap := range container.SecurityContext.Capabilities.Add {
|
for _, cap := range capabilities.Add {
|
||||||
sCap := string(cap)
|
sCap := string(cap)
|
||||||
if !defaultAdd.Has(sCap) && !allowedAdd.Has(sCap) {
|
if !defaultAdd.Has(sCap) && !allowedAdd.Has(sCap) {
|
||||||
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "add"), sCap, "capability may not be added"))
|
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "add"), sCap, "capability may not be added"))
|
||||||
@ -124,12 +117,12 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container) f
|
|||||||
}
|
}
|
||||||
|
|
||||||
// validate that anything that is required to be dropped is in the drop set
|
// validate that anything that is required to be dropped is in the drop set
|
||||||
containerDrops := makeCapSet(container.SecurityContext.Capabilities.Drop)
|
containerDrops := makeCapSet(capabilities.Drop)
|
||||||
|
|
||||||
for _, requiredDrop := range s.requiredDropCapabilities {
|
for _, requiredDrop := range s.requiredDropCapabilities {
|
||||||
sDrop := string(requiredDrop)
|
sDrop := string(requiredDrop)
|
||||||
if !containerDrops.Has(sDrop) {
|
if !containerDrops.Has(sDrop) {
|
||||||
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "drop"), container.SecurityContext.Capabilities.Drop,
|
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "drop"), capabilities.Drop,
|
||||||
fmt.Sprintf("%s is required to be dropped but was not found", sDrop)))
|
fmt.Sprintf("%s is required to be dropped but was not found", sDrop)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,18 +324,12 @@ func TestValidateAdds(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range tests {
|
for k, v := range tests {
|
||||||
container := &api.Container{
|
|
||||||
SecurityContext: &api.SecurityContext{
|
|
||||||
Capabilities: v.containerCaps,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
strategy, err := NewDefaultCapabilities(v.defaultAddCaps, nil, v.allowedCaps)
|
strategy, err := NewDefaultCapabilities(v.defaultAddCaps, nil, v.allowedCaps)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s failed: %v", k, err)
|
t.Errorf("%s failed: %v", k, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
errs := strategy.Validate(nil, container)
|
errs := strategy.Validate(nil, nil, v.containerCaps)
|
||||||
if v.expectedError == "" && len(errs) > 0 {
|
if v.expectedError == "" && len(errs) > 0 {
|
||||||
t.Errorf("%s should have passed but had errors %v", k, errs)
|
t.Errorf("%s should have passed but had errors %v", k, errs)
|
||||||
continue
|
continue
|
||||||
@ -391,18 +385,12 @@ func TestValidateDrops(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range tests {
|
for k, v := range tests {
|
||||||
container := &api.Container{
|
|
||||||
SecurityContext: &api.SecurityContext{
|
|
||||||
Capabilities: v.containerCaps,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
strategy, err := NewDefaultCapabilities(nil, v.requiredDropCaps, nil)
|
strategy, err := NewDefaultCapabilities(nil, v.requiredDropCaps, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("%s failed: %v", k, err)
|
t.Errorf("%s failed: %v", k, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
errs := strategy.Validate(nil, container)
|
errs := strategy.Validate(nil, nil, v.containerCaps)
|
||||||
if v.expectedError == "" && len(errs) > 0 {
|
if v.expectedError == "" && len(errs) > 0 {
|
||||||
t.Errorf("%s should have passed but had errors %v", k, errs)
|
t.Errorf("%s should have passed but had errors %v", k, errs)
|
||||||
continue
|
continue
|
||||||
|
@ -26,5 +26,5 @@ type Strategy interface {
|
|||||||
// Generate creates the capabilities based on policy rules.
|
// Generate creates the capabilities based on policy rules.
|
||||||
Generate(pod *api.Pod, container *api.Container) (*api.Capabilities, error)
|
Generate(pod *api.Pod, container *api.Container) (*api.Capabilities, error)
|
||||||
// Validate ensures that the specified values fall within the range of the strategy.
|
// Validate ensures that the specified values fall within the range of the strategy.
|
||||||
Validate(pod *api.Pod, container *api.Container) field.ErrorList
|
Validate(pod *api.Pod, container *api.Container, capabilities *api.Capabilities) field.ErrorList
|
||||||
}
|
}
|
||||||
|
@ -283,7 +283,7 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe
|
|||||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("privileged"), *sc.Privileged, "Privileged containers are not allowed"))
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("privileged"), *sc.Privileged, "Privileged containers are not allowed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
allErrs = append(allErrs, s.strategies.CapabilitiesStrategy.Validate(pod, container)...)
|
allErrs = append(allErrs, s.strategies.CapabilitiesStrategy.Validate(pod, container, sc.Capabilities)...)
|
||||||
|
|
||||||
if !s.psp.Spec.HostNetwork && pod.Spec.SecurityContext.HostNetwork {
|
if !s.psp.Spec.HostNetwork && pod.Spec.SecurityContext.HostNetwork {
|
||||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("hostNetwork"), pod.Spec.SecurityContext.HostNetwork, "Host network is not allowed to be used"))
|
allErrs = append(allErrs, field.Invalid(fldPath.Child("hostNetwork"), pod.Spec.SecurityContext.HostNetwork, "Host network is not allowed to be used"))
|
||||||
|
Loading…
Reference in New Issue
Block a user