Skip to content

Commit 58e31d1

Browse files
committed
fix: uniqMcs use all cpu
Signed-off-by: ningmingxiao <ning.mingxiao@zte.com.cn>
1 parent f148739 commit 58e31d1

3 files changed

Lines changed: 33 additions & 4 deletions

File tree

go-selinux/label/label_linux.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ var validOptions = map[string]bool{
1818
"level": true,
1919
}
2020

21-
var ErrIncompatibleLabel = errors.New("bad SELinux option: z and Z can not be used together")
21+
var (
22+
maxSelinuxLabelSize = int(selinux.CategoryRange * (selinux.CategoryRange - 1) / 2)
23+
ErrIncompatibleLabel = errors.New("bad SELinux option: z and Z can not be used together")
24+
)
2225

2326
// InitLabels returns the process label and file labels to be used within
2427
// the container. A list of options can be passed into this function to alter
@@ -30,6 +33,9 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) {
3033
if !selinux.GetEnabled() {
3134
return "", "", nil
3235
}
36+
if size := selinux.ContainerLabelsSize(); size >= maxSelinuxLabelSize {
37+
return "", "", fmt.Errorf("SELinux label exhaustion: %d labels used", size)
38+
}
3339
processLabel, mountLabel := selinux.ContainerLabels()
3440
if processLabel == "" {
3541
// processLabel is required; if empty, do nothing.

go-selinux/label/label_linux_test.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package label
33
import (
44
"errors"
55
"os"
6+
"strings"
67
"testing"
78

89
"github.com/opencontainers/selinux/go-selinux"
@@ -53,6 +54,22 @@ func TestInit(t *testing.T) {
5354
}
5455
}
5556

57+
func TestSELinuxLabelExhaustion(t *testing.T) {
58+
needSELinux(t)
59+
selinux.CategoryRange = 5
60+
var testNull []string
61+
for i := 0; i < 20; i++ {
62+
_, _, err := InitLabels(testNull)
63+
if i == 19 {
64+
if err == nil {
65+
t.Fatal("err should not be nil")
66+
} else if !strings.Contains(err.Error(), "SELinux label exhaustion") {
67+
t.Fatalf("unexpected error %s", err.Error())
68+
}
69+
}
70+
}
71+
}
72+
5673
func TestRelabel(t *testing.T) {
5774
needSELinux(t)
5875

go-selinux/selinux_linux.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ type selinuxState struct {
4444
selinuxfsOnce sync.Once
4545
enabledSet bool
4646
enabled bool
47-
sync.Mutex
47+
sync.RWMutex
4848
}
4949

5050
type level struct {
@@ -92,6 +92,12 @@ var policyRoot = sync.OnceValue(func() string {
9292
return filepath.Join(selinuxDir, readConfig(selinuxTypeTag))
9393
})
9494

95+
func ContainerLabelsSize() int {
96+
state.RLock()
97+
defer state.RUnlock()
98+
return len(state.mcsList)
99+
}
100+
95101
func (s *selinuxState) setEnable(enabled bool) bool {
96102
s.Lock()
97103
defer s.Unlock()
@@ -862,8 +868,8 @@ func checkLabel(label string) error {
862868
if len(label) != 0 {
863869
con := strings.SplitN(label, ":", 4)
864870
if len(con) > 3 {
865-
state.Lock()
866-
defer state.Unlock()
871+
state.RLock()
872+
defer state.RUnlock()
867873
if state.mcsList[con[3]] {
868874
return ErrMCSAlreadyExists
869875
}

0 commit comments

Comments
 (0)