Skip to content

Commit

Permalink
SecurityContextConstraints: pass effective capabilities to validation…
Browse files Browse the repository at this point in the history
… interface.
  • Loading branch information
php-coder committed Dec 18, 2017
1 parent 1b41ef7 commit 098d160
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 29 deletions.
19 changes: 6 additions & 13 deletions pkg/security/securitycontextconstraints/capabilities/mustrunas.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,10 @@ func (s *defaultCapabilities) Generate(pod *api.Pod, container *api.Container) (
}

// 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{}

// if the security context isn't set then we haven't generated correctly. Shouldn't get here
// 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 capabilities == nil {
// if container.SC.Caps is nil then nothing was defaulted by the strat or requested by the pod author
// 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.
Expand All @@ -86,7 +79,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
// 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"))
return allErrs
}
Expand All @@ -101,20 +94,20 @@ func (s *defaultCapabilities) Validate(pod *api.Pod, container *api.Container) f
// validate that anything being added is in the default or allowed sets
defaultAdd := makeCapSet(s.defaultAddCapabilities)

for _, cap := range container.SecurityContext.Capabilities.Add {
for _, cap := range capabilities.Add {
sCap := string(cap)
if !defaultAdd.Has(sCap) && !allowedAdd.Has(sCap) {
allErrs = append(allErrs, field.Invalid(field.NewPath("capabilities", "add"), sCap, "capability may not be added"))
}
}

// 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 {
sDrop := string(requiredDrop)
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)))
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,18 +321,12 @@ func TestValidateAdds(t *testing.T) {
}

for k, v := range tests {
container := &api.Container{
SecurityContext: &api.SecurityContext{
Capabilities: v.containerCaps,
},
}

strategy, err := NewDefaultCapabilities(v.defaultAddCaps, v.requiredDropCaps, v.allowedCaps)
if err != nil {
t.Errorf("%s failed: %v", k, err)
continue
}
errs := strategy.Validate(nil, container)
errs := strategy.Validate(nil, nil, v.containerCaps)
if v.shouldPass && len(errs) > 0 {
t.Errorf("%s should have passed but had errors %v", k, errs)
continue
Expand Down Expand Up @@ -384,18 +378,12 @@ func TestValidateDrops(t *testing.T) {
}

for k, v := range tests {
container := &api.Container{
SecurityContext: &api.SecurityContext{
Capabilities: v.containerCaps,
},
}

strategy, err := NewDefaultCapabilities(v.defaultAddCaps, v.requiredDropCaps, nil)
if err != nil {
t.Errorf("%s failed: %v", k, err)
continue
}
errs := strategy.Validate(nil, container)
errs := strategy.Validate(nil, nil, v.containerCaps)
if v.shouldPass && len(errs) > 0 {
t.Errorf("%s should have passed but had errors %v", k, errs)
continue
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ type CapabilitiesSecurityContextConstraintsStrategy interface {
// Generate creates the capabilities based on policy rules.
Generate(pod *api.Pod, container *api.Container) (*api.Capabilities, error)
// 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
}
2 changes: 1 addition & 1 deletion pkg/security/securitycontextconstraints/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,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, s.capabilitiesStrategy.Validate(pod, container)...)
allErrs = append(allErrs, s.capabilitiesStrategy.Validate(pod, container, sc.Capabilities)...)

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"))
Expand Down

0 comments on commit 098d160

Please sign in to comment.