diff --git a/go-selinux/label/label_linux.go b/go-selinux/label/label_linux.go index 95f29e2..05613a5 100644 --- a/go-selinux/label/label_linux.go +++ b/go-selinux/label/label_linux.go @@ -30,6 +30,9 @@ func InitLabels(options []string) (plabel string, mlabel string, retErr error) { if !selinux.GetEnabled() { return "", "", nil } + if selinux.GetContainerLabelsSize() == int(selinux.CategoryRange*(selinux.CategoryRange-1)/2) { + return "", "", fmt.Errorf("SELinux label exhaustion: %d labels used", selinux.GetContainerLabelsSize()) + } processLabel, mountLabel := selinux.ContainerLabels() if processLabel != "" { defer func() { diff --git a/go-selinux/label/label_linux_test.go b/go-selinux/label/label_linux_test.go index e25ead7..ba45c13 100644 --- a/go-selinux/label/label_linux_test.go +++ b/go-selinux/label/label_linux_test.go @@ -2,6 +2,7 @@ package label import ( "errors" + "fmt" "os" "testing" @@ -53,6 +54,22 @@ func TestInit(t *testing.T) { } } +func TestSELinuxLabelExhaustion(t *testing.T) { + needSELinux(t) + selinux.CategoryRange = 5 + var testNull []string + for i := 0; i < 20; i++ { + _, _, err := InitLabels(testNull) + if i == 19 { + if err == nil { + t.Fatal("err should not be nil") + } else if err.Error() != fmt.Sprintf("SELinux label exhaustion: %d labels used", selinux.GetContainerLabelsSize()) { + t.Fatalf("unexpected error %s", err.Error()) + } + } + } +} + func TestRelabel(t *testing.T) { needSELinux(t) diff --git a/go-selinux/selinux_linux.go b/go-selinux/selinux_linux.go index 6d7f8e2..d3d1223 100644 --- a/go-selinux/selinux_linux.go +++ b/go-selinux/selinux_linux.go @@ -85,6 +85,12 @@ var ( labels map[string]string ) +func GetContainerLabelsSize() int { + state.Lock() + defer state.Unlock() + return len(state.mcsList) +} + func policyRoot() string { policyRootOnce.Do(func() { policyRootVal = filepath.Join(selinuxDir, readConfig(selinuxTypeTag))