Skip to content
This repository has been archived by the owner on Mar 9, 2022. It is now read-only.

Commit

Permalink
Merge pull request #873 from miaoyq/verify-selinux-level
Browse files Browse the repository at this point in the history
Verify selinux level format
  • Loading branch information
Random-Liu committed Aug 14, 2018
2 parents 7d483b2 + a87bda0 commit 58eb045
Show file tree
Hide file tree
Showing 7 changed files with 515 additions and 84 deletions.
22 changes: 20 additions & 2 deletions pkg/server/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"fmt"
"path"
"path/filepath"
"regexp"
"strconv"
"strings"

Expand Down Expand Up @@ -370,11 +371,16 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error)
// Should ignored selinuxOpts if they are incomplete.
if selinuxOpt.GetUser() == "" ||
selinuxOpt.GetRole() == "" ||
selinuxOpt.GetType() == "" ||
selinuxOpt.GetLevel() == "" {
selinuxOpt.GetType() == "" {
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",
selinuxOpt.GetUser(),
selinuxOpt.GetRole(),
Expand All @@ -383,6 +389,18 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error)
return label.InitLabels(selinux.DupSecOpt(labelOpts))
}

func checkSelinuxLevel(level string) (bool, error) {
if len(level) == 0 {
return true, nil
}

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.
func isInCRIMounts(dst string, mounts []*runtime.Mount) bool {
for _, m := range mounts {
Expand Down
104 changes: 101 additions & 3 deletions pkg/server/helpers_selinux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ limitations under the License.
package server

import (
"strings"
"testing"

"github.com/opencontainers/selinux/go-selinux"
Expand All @@ -35,6 +36,7 @@ func TestInitSelinuxOpts(t *testing.T) {
selinuxOpt *runtime.SELinuxOption
processLabel string
mountLabels []string
expectErr bool
}{
"Should return empty strings for processLabel and mountLabel when selinuxOpt is nil": {
selinuxOpt: nil,
Expand All @@ -61,12 +63,108 @@ func TestInitSelinuxOpts(t *testing.T) {
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"},
},
"Should be resolved correctly when selinuxOpt has been initialized with level=''": {
selinuxOpt: &runtime.SELinuxOption{
User: "user_u",
Role: "user_r",
Type: "user_t",
Level: "",
},
processLabel: "user_u:user_r:user_t:s0",
mountLabels: []string{"user_u:object_r:container_file_t:s0", "user_u:object_r:svirt_sandbox_file_t:s0"},
},
"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) {
processLabel, mountLabel, err := initSelinuxOpts(test.selinuxOpt)
assert.NoError(t, err)
assert.Equal(t, test.processLabel, processLabel)
assert.Contains(t, test.mountLabels, mountLabel)
if test.expectErr {
assert.Error(t, err)
} else {
assert.NoError(t, err)
if test.selinuxOpt == nil || test.selinuxOpt.Level != "" {
assert.Equal(t, test.processLabel, processLabel)
assert.Contains(t, test.mountLabels, mountLabel)
} else {
assert.Equal(t, 0, strings.LastIndex(processLabel, test.processLabel))
contain := strings.LastIndex(mountLabel, test.mountLabels[0]) == 0 ||
strings.LastIndex(mountLabel, test.mountLabels[1]) == 0
assert.True(t, contain)
}
}
})
}
}

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)
}
})
}
}
2 changes: 1 addition & 1 deletion vendor.conf
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ github.com/opencontainers/image-spec v1.0.1
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
github.com/opencontainers/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce
github.com/opencontainers/runtime-tools v0.6.0
github.com/opencontainers/selinux 4a2974bf1ee960774ffd517717f1f45325af0206
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
github.com/pkg/errors v0.8.0
github.com/pmezard/go-difflib v1.0.0
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 58eb045

Please sign in to comment.