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

Commit 58eb045

Browse files
authored
Merge pull request #873 from miaoyq/verify-selinux-level
Verify selinux level format
2 parents 7d483b2 + a87bda0 commit 58eb045

7 files changed

Lines changed: 515 additions & 84 deletions

File tree

pkg/server/helpers.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"fmt"
2222
"path"
2323
"path/filepath"
24+
"regexp"
2425
"strconv"
2526
"strings"
2627

@@ -370,11 +371,16 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error)
370371
// Should ignored selinuxOpts if they are incomplete.
371372
if selinuxOpt.GetUser() == "" ||
372373
selinuxOpt.GetRole() == "" ||
373-
selinuxOpt.GetType() == "" ||
374-
selinuxOpt.GetLevel() == "" {
374+
selinuxOpt.GetType() == "" {
375375
return "", "", nil
376376
}
377377

378+
// make sure the format of "level" is correct.
379+
ok, err := checkSelinuxLevel(selinuxOpt.GetLevel())
380+
if err != nil || !ok {
381+
return "", "", err
382+
}
383+
378384
labelOpts := fmt.Sprintf("%s:%s:%s:%s",
379385
selinuxOpt.GetUser(),
380386
selinuxOpt.GetRole(),
@@ -383,6 +389,18 @@ func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error)
383389
return label.InitLabels(selinux.DupSecOpt(labelOpts))
384390
}
385391

392+
func checkSelinuxLevel(level string) (bool, error) {
393+
if len(level) == 0 {
394+
return true, nil
395+
}
396+
397+
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)
398+
if err != nil || !matched {
399+
return false, fmt.Errorf("the format of 'level' %q is not correct: %v", level, err)
400+
}
401+
return true, nil
402+
}
403+
386404
// isInCRIMounts checks whether a destination is in CRI mount list.
387405
func isInCRIMounts(dst string, mounts []*runtime.Mount) bool {
388406
for _, m := range mounts {

pkg/server/helpers_selinux_test.go

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ limitations under the License.
1919
package server
2020

2121
import (
22+
"strings"
2223
"testing"
2324

2425
"github.com/opencontainers/selinux/go-selinux"
@@ -35,6 +36,7 @@ func TestInitSelinuxOpts(t *testing.T) {
3536
selinuxOpt *runtime.SELinuxOption
3637
processLabel string
3738
mountLabels []string
39+
expectErr bool
3840
}{
3941
"Should return empty strings for processLabel and mountLabel when selinuxOpt is nil": {
4042
selinuxOpt: nil,
@@ -61,12 +63,108 @@ func TestInitSelinuxOpts(t *testing.T) {
6163
processLabel: "user_u:user_r:user_t:s0:c1,c2",
6264
mountLabels: []string{"user_u:object_r:container_file_t:s0:c1,c2", "user_u:object_r:svirt_sandbox_file_t:s0:c1,c2"},
6365
},
66+
"Should be resolved correctly when selinuxOpt has been initialized with level=''": {
67+
selinuxOpt: &runtime.SELinuxOption{
68+
User: "user_u",
69+
Role: "user_r",
70+
Type: "user_t",
71+
Level: "",
72+
},
73+
processLabel: "user_u:user_r:user_t:s0",
74+
mountLabels: []string{"user_u:object_r:container_file_t:s0", "user_u:object_r:svirt_sandbox_file_t:s0"},
75+
},
76+
"Should return error when the format of 'level' is not correct": {
77+
selinuxOpt: &runtime.SELinuxOption{
78+
User: "user_u",
79+
Role: "user_r",
80+
Type: "user_t",
81+
Level: "s0,c1,c2",
82+
},
83+
expectErr: true,
84+
},
6485
} {
6586
t.Run(desc, func(t *testing.T) {
6687
processLabel, mountLabel, err := initSelinuxOpts(test.selinuxOpt)
67-
assert.NoError(t, err)
68-
assert.Equal(t, test.processLabel, processLabel)
69-
assert.Contains(t, test.mountLabels, mountLabel)
88+
if test.expectErr {
89+
assert.Error(t, err)
90+
} else {
91+
assert.NoError(t, err)
92+
if test.selinuxOpt == nil || test.selinuxOpt.Level != "" {
93+
assert.Equal(t, test.processLabel, processLabel)
94+
assert.Contains(t, test.mountLabels, mountLabel)
95+
} else {
96+
assert.Equal(t, 0, strings.LastIndex(processLabel, test.processLabel))
97+
contain := strings.LastIndex(mountLabel, test.mountLabels[0]) == 0 ||
98+
strings.LastIndex(mountLabel, test.mountLabels[1]) == 0
99+
assert.True(t, contain)
100+
}
101+
}
102+
})
103+
}
104+
}
105+
106+
func TestCheckSelinuxLevel(t *testing.T) {
107+
for desc, test := range map[string]struct {
108+
level string
109+
expectErr bool
110+
}{
111+
"s0": {
112+
level: "s0",
113+
},
114+
"s0-s0": {
115+
level: "s0-s0",
116+
},
117+
"s0:c0": {
118+
level: "s0:c0",
119+
},
120+
"s0:c0.c3": {
121+
level: "s0:c0.c3",
122+
},
123+
"s0:c0,c3": {
124+
level: "s0:c0,c3",
125+
},
126+
"s0-s0:c0,c3": {
127+
level: "s0-s0:c0,c3",
128+
},
129+
"s0-s0:c0,c3.c6": {
130+
level: "s0-s0:c0,c3.c6",
131+
},
132+
"s0-s0:c0,c3.c6,c8.c10": {
133+
level: "s0-s0:c0,c3.c6,c8.c10",
134+
},
135+
"s0-s0:c0,c3.c6,c8,c10": {
136+
level: "s0-s0:c0,c3.c6",
137+
},
138+
"s0,c0,c3": {
139+
level: "s0,c0,c3",
140+
expectErr: true,
141+
},
142+
"s0:c0.c3.c6": {
143+
level: "s0:c0.c3.c6",
144+
expectErr: true,
145+
},
146+
"s0-s0,c0,c3": {
147+
level: "s0-s0,c0,c3",
148+
expectErr: true,
149+
},
150+
"s0-s0:c0.c3.c6": {
151+
level: "s0-s0:c0.c3.c6",
152+
expectErr: true,
153+
},
154+
"s0-s0:c0,c3.c6.c8": {
155+
level: "s0-s0:c0,c3.c6.c8",
156+
expectErr: true,
157+
},
158+
} {
159+
t.Run(desc, func(t *testing.T) {
160+
ok, err := checkSelinuxLevel(test.level)
161+
if test.expectErr {
162+
assert.Error(t, err)
163+
assert.False(t, ok)
164+
} else {
165+
assert.NoError(t, err)
166+
assert.True(t, ok)
167+
}
70168
})
71169
}
72170
}

vendor.conf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ github.com/opencontainers/image-spec v1.0.1
4343
github.com/opencontainers/runc 69663f0bd4b60df09991c08812a60108003fa340
4444
github.com/opencontainers/runtime-spec d810dbc60d8c5aeeb3d054bd1132fab2121968ce
4545
github.com/opencontainers/runtime-tools v0.6.0
46-
github.com/opencontainers/selinux 4a2974bf1ee960774ffd517717f1f45325af0206
46+
github.com/opencontainers/selinux b6fa367ed7f534f9ba25391cc2d467085dbb445a
4747
github.com/pkg/errors v0.8.0
4848
github.com/pmezard/go-difflib v1.0.0
4949
github.com/prometheus/client_golang f4fb1b73fb099f396a7f0036bf86aa8def4ed823

vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go

Lines changed: 3 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)