mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 03:41:45 +00:00
PSP: when comparing categories in SELinux levels, ignore its order.
This commit is contained in:
parent
2f4cca73af
commit
072214597c
@ -18,10 +18,13 @@ package selinux
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
|
||||
)
|
||||
|
||||
type mustRunAs struct {
|
||||
@ -55,7 +58,7 @@ func (s *mustRunAs) Validate(fldPath *field.Path, _ *api.Pod, _ *api.Container,
|
||||
allErrs = append(allErrs, field.Required(fldPath, ""))
|
||||
return allErrs
|
||||
}
|
||||
if seLinux.Level != s.opts.SELinuxOptions.Level {
|
||||
if !equalLevels(s.opts.SELinuxOptions.Level, seLinux.Level) {
|
||||
detail := fmt.Sprintf("must be %s", s.opts.SELinuxOptions.Level)
|
||||
allErrs = append(allErrs, field.Invalid(fldPath.Child("level"), seLinux.Level, detail))
|
||||
}
|
||||
@ -74,3 +77,44 @@ func (s *mustRunAs) Validate(fldPath *field.Path, _ *api.Pod, _ *api.Container,
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// equalLevels compares SELinux levels for equality.
|
||||
func equalLevels(expected, actual string) bool {
|
||||
if expected == actual {
|
||||
return true
|
||||
}
|
||||
// "s0:c6,c0" => [ "s0", "c6,c0" ]
|
||||
expectedParts := strings.SplitN(expected, ":", 2)
|
||||
actualParts := strings.SplitN(actual, ":", 2)
|
||||
|
||||
// both SELinux levels must be in a format "sX:cY"
|
||||
if len(expectedParts) != 2 || len(actualParts) != 2 {
|
||||
return false
|
||||
}
|
||||
|
||||
if !equalSensitivity(expectedParts[0], actualParts[0]) {
|
||||
return false
|
||||
}
|
||||
|
||||
if !equalCategories(expectedParts[1], actualParts[1]) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// equalSensitivity compares sensitivities of the SELinux levels for equality.
|
||||
func equalSensitivity(expected, actual string) bool {
|
||||
return expected == actual
|
||||
}
|
||||
|
||||
// equalCategories compares categories of the SELinux levels for equality.
|
||||
func equalCategories(expected, actual string) bool {
|
||||
expectedCategories := strings.Split(expected, ",")
|
||||
actualCategories := strings.Split(actual, ",")
|
||||
|
||||
sort.Strings(expectedCategories)
|
||||
sort.Strings(actualCategories)
|
||||
|
||||
return util.EqualStringSlices(expectedCategories, actualCategories)
|
||||
}
|
||||
|
@ -76,11 +76,17 @@ func TestMustRunAsValidate(t *testing.T) {
|
||||
return &api.SELinuxOptions{
|
||||
User: "user",
|
||||
Role: "role",
|
||||
Level: "level",
|
||||
Level: "s0:c0,c6",
|
||||
Type: "type",
|
||||
}
|
||||
}
|
||||
|
||||
newValidOptsWithLevel := func(level string) *api.SELinuxOptions {
|
||||
opts := newValidOpts()
|
||||
opts.Level = level
|
||||
return opts
|
||||
}
|
||||
|
||||
role := newValidOpts()
|
||||
role.Role = "invalid"
|
||||
|
||||
@ -117,6 +123,10 @@ func TestMustRunAsValidate(t *testing.T) {
|
||||
seLinux: newValidOpts(),
|
||||
expectedMsg: "",
|
||||
},
|
||||
"valid with different order of categories": {
|
||||
seLinux: newValidOptsWithLevel("s0:c6,c0"),
|
||||
expectedMsg: "",
|
||||
},
|
||||
}
|
||||
|
||||
opts := &extensions.SELinuxStrategyOptions{
|
||||
|
@ -222,3 +222,17 @@ func hasPathPrefix(s, pathPrefix string) bool {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// EqualStringSlices compares string slices for equality. Slices are equal when
|
||||
// their sizes and elements on similar positions are equal.
|
||||
func EqualStringSlices(a, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(a); i++ {
|
||||
if a[i] != b[i] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -194,3 +194,38 @@ func TestAllowsHostVolumePath(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEqualStringSlices(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
arg1 []string
|
||||
arg2 []string
|
||||
expectedResult bool
|
||||
}{
|
||||
"nil equals to nil": {
|
||||
arg1: nil,
|
||||
arg2: nil,
|
||||
expectedResult: true,
|
||||
},
|
||||
"equal by size": {
|
||||
arg1: []string{"1", "1"},
|
||||
arg2: []string{"1", "1"},
|
||||
expectedResult: true,
|
||||
},
|
||||
"not equal by size": {
|
||||
arg1: []string{"1"},
|
||||
arg2: []string{"1", "1"},
|
||||
expectedResult: false,
|
||||
},
|
||||
"not equal by elements": {
|
||||
arg1: []string{"1", "1"},
|
||||
arg2: []string{"1", "2"},
|
||||
expectedResult: false,
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range tests {
|
||||
if result := EqualStringSlices(v.arg1, v.arg2); result != v.expectedResult {
|
||||
t.Errorf("%s expected to return %t but got %t", k, v.expectedResult, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user