verify selinux level format

Signed-off-by: Yanqiang Miao <miao.yanqiang@zte.com.cn>
This commit is contained in:
Yanqiang Miao 2018-08-08 17:32:01 +08:00
parent c9d6151526
commit 415727cd9f
2 changed files with 98 additions and 3 deletions

View File

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"path" "path"
"path/filepath" "path/filepath"
"regexp"
"strconv" "strconv"
"strings" "strings"
@ -375,6 +376,12 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error)
return "", "", nil return "", "", nil
} }
// make sure the format of "level" is correct.
ok, err := checkSelinuxLevel(selinuxOpt.GetLevel())
if err != nil || !ok {
return "", "", err
}
labelOpts := fmt.Sprintf("%s:%s:%s:%s", labelOpts := fmt.Sprintf("%s:%s:%s:%s",
selinuxOpt.GetUser(), selinuxOpt.GetUser(),
selinuxOpt.GetRole(), selinuxOpt.GetRole(),
@ -383,6 +390,14 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error)
return label.InitLabels(selinux.DupSecOpt(labelOpts)) return label.InitLabels(selinux.DupSecOpt(labelOpts))
} }
func checkSelinuxLevel(level string) (bool, error) {
matched, err := regexp.MatchString(`^s\d(-s\d)??(:c\d{1,4}((.c\d{1,4})?,c\d{1,4})*(.c\d{1,4})?(,c\d{1,4}(.c\d{1,4})?)*)?$`, level)
if err != nil || !matched {
return false, fmt.Errorf("the format of 'level' %q is not correct: %v", level, err)
}
return true, nil
}
// isInCRIMounts checks whether a destination is in CRI mount list. // isInCRIMounts checks whether a destination is in CRI mount list.
func isInCRIMounts(dst string, mounts []*runtime.Mount) bool { func isInCRIMounts(dst string, mounts []*runtime.Mount) bool {
for _, m := range mounts { for _, m := range mounts {

View File

@ -35,6 +35,7 @@ func TestInitSelinuxOpts(t *testing.T) {
selinuxOpt *runtime.SELinuxOption selinuxOpt *runtime.SELinuxOption
processLabel string processLabel string
mountLabels []string mountLabels []string
expectErr bool
}{ }{
"Should return empty strings for processLabel and mountLabel when selinuxOpt is nil": { "Should return empty strings for processLabel and mountLabel when selinuxOpt is nil": {
selinuxOpt: nil, selinuxOpt: nil,
@ -61,12 +62,91 @@ func TestInitSelinuxOpts(t *testing.T) {
processLabel: "user_u:user_r:user_t:s0:c1,c2", processLabel: "user_u:user_r:user_t:s0:c1,c2",
mountLabels: []string{"user_u:object_r:container_file_t:s0:c1,c2", "user_u:object_r:svirt_sandbox_file_t:s0:c1,c2"}, mountLabels: []string{"user_u:object_r:container_file_t:s0:c1,c2", "user_u:object_r:svirt_sandbox_file_t:s0:c1,c2"},
}, },
"Should return error when the format of 'level' is not correct": {
selinuxOpt: &runtime.SELinuxOption{
User: "user_u",
Role: "user_r",
Type: "user_t",
Level: "s0,c1,c2",
},
expectErr: true,
},
} { } {
t.Run(desc, func(t *testing.T) { t.Run(desc, func(t *testing.T) {
processLabel, mountLabel, err := initSelinuxOpts(test.selinuxOpt) processLabel, mountLabel, err := initSelinuxOpts(test.selinuxOpt)
if test.expectErr {
assert.Error(t, err)
} else {
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, test.processLabel, processLabel) assert.Equal(t, test.processLabel, processLabel)
assert.Contains(t, test.mountLabels, mountLabel) assert.Contains(t, test.mountLabels, mountLabel)
}
})
}
}
func TestCheckSelinuxLevel(t *testing.T) {
for desc, test := range map[string]struct {
level string
expectErr bool
}{
"s0": {
level: "s0",
},
"s0-s0": {
level: "s0-s0",
},
"s0:c0": {
level: "s0:c0",
},
"s0:c0.c3": {
level: "s0:c0.c3",
},
"s0:c0,c3": {
level: "s0:c0,c3",
},
"s0-s0:c0,c3": {
level: "s0-s0:c0,c3",
},
"s0-s0:c0,c3.c6": {
level: "s0-s0:c0,c3.c6",
},
"s0-s0:c0,c3.c6,c8.c10": {
level: "s0-s0:c0,c3.c6,c8.c10",
},
"s0-s0:c0,c3.c6,c8,c10": {
level: "s0-s0:c0,c3.c6",
},
"s0,c0,c3": {
level: "s0,c0,c3",
expectErr: true,
},
"s0:c0.c3.c6": {
level: "s0:c0.c3.c6",
expectErr: true,
},
"s0-s0,c0,c3": {
level: "s0-s0,c0,c3",
expectErr: true,
},
"s0-s0:c0.c3.c6": {
level: "s0-s0:c0.c3.c6",
expectErr: true,
},
"s0-s0:c0,c3.c6.c8": {
level: "s0-s0:c0,c3.c6.c8",
expectErr: true,
},
} {
t.Run(desc, func(t *testing.T) {
ok, err := checkSelinuxLevel(test.level)
if test.expectErr {
assert.Error(t, err)
assert.False(t, ok)
} else {
assert.NoError(t, err)
assert.True(t, ok)
}
}) })
} }
} }