@@ -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
5050type 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+
95101func (s * selinuxState ) setEnable (enabled bool ) bool {
96102 s .Lock ()
97103 defer s .Unlock ()
@@ -243,12 +249,9 @@ func readConfig(target string) string {
243249 // Skip comments
244250 continue
245251 }
246- fields := bytes .SplitN (line , []byte {'=' }, 2 )
247- if len (fields ) != 2 {
248- continue
249- }
250- if bytes .Equal (fields [0 ], []byte (target )) {
251- return string (bytes .Trim (fields [1 ], `"` ))
252+ key , val , ok := bytes .Cut (line , []byte {'=' })
253+ if ok && string (key ) == target {
254+ return string (bytes .Trim (val , `"` ))
252255 }
253256 }
254257 return ""
@@ -580,21 +583,20 @@ func catsToBitset(cats string) (*big.Int, error) {
580583
581584 catlist := strings .Split (cats , "," )
582585 for _ , r := range catlist {
583- ranges := strings .SplitN (r , "." , 2 )
584- if len (ranges ) > 1 {
585- catstart , err := parseLevelItem (ranges [0 ], category )
586+ if s , e , ok := strings .Cut (r , "." ); ok {
587+ catstart , err := parseLevelItem (s , category )
586588 if err != nil {
587589 return nil , err
588590 }
589- catend , err := parseLevelItem (ranges [ 1 ] , category )
591+ catend , err := parseLevelItem (e , category )
590592 if err != nil {
591593 return nil , err
592594 }
593595 for i := catstart ; i <= catend ; i ++ {
594596 bitset .SetBit (bitset , i , 1 )
595597 }
596598 } else {
597- cat , err := parseLevelItem (ranges [ 0 ] , category )
599+ cat , err := parseLevelItem (r , category )
598600 if err != nil {
599601 return nil , err
600602 }
@@ -622,14 +624,14 @@ func parseLevelItem(s string, sep levelItem) (int, error) {
622624// parseLevel fills a level from a string that contains
623625// a sensitivity and categories
624626func (l * level ) parseLevel (levelStr string ) error {
625- lvl := strings .SplitN (levelStr , ":" , 2 )
626- sens , err := parseLevelItem (lvl [ 0 ] , sensitivity )
627+ s , c , ok := strings .Cut (levelStr , ":" )
628+ sens , err := parseLevelItem (s , sensitivity )
627629 if err != nil {
628630 return fmt .Errorf ("failed to parse sensitivity: %w" , err )
629631 }
630632 l .sens = sens
631- if len ( lvl ) > 1 {
632- cats , err := catsToBitset (lvl [ 1 ] )
633+ if ok {
634+ cats , err := catsToBitset (c )
633635 if err != nil {
634636 return fmt .Errorf ("failed to parse categories: %w" , err )
635637 }
@@ -642,25 +644,19 @@ func (l *level) parseLevel(levelStr string) error {
642644// rangeStrToMLSRange marshals a string representation of a range.
643645func rangeStrToMLSRange (rangeStr string ) (* mlsRange , error ) {
644646 r := & mlsRange {}
645- l := strings .SplitN (rangeStr , "-" , 2 )
646-
647- switch len (l ) {
648- // rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023
649- case 2 :
647+ lo , hi , ok := strings .Cut (rangeStr , "-" )
648+ r .low = & level {}
649+ if err := r .low .parseLevel (lo ); err != nil {
650+ return nil , fmt .Errorf ("failed to parse low level %q: %w" , lo , err )
651+ }
652+ if ok {
653+ // rangeStr that has a low and a high level, e.g. s4:c0.c1023-s6:c0.c1023.
650654 r .high = & level {}
651- if err := r .high .parseLevel (l [ 1 ] ); err != nil {
652- return nil , fmt .Errorf ("failed to parse high level %q: %w" , l [ 1 ] , err )
655+ if err := r .high .parseLevel (hi ); err != nil {
656+ return nil , fmt .Errorf ("failed to parse high level %q: %w" , hi , err )
653657 }
654- fallthrough
655- // rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023
656- case 1 :
657- r .low = & level {}
658- if err := r .low .parseLevel (l [0 ]); err != nil {
659- return nil , fmt .Errorf ("failed to parse low level %q: %w" , l [0 ], err )
660- }
661- }
662-
663- if r .high == nil {
658+ } else {
659+ // rangeStr that is single level, e.g. s6:c0,c3,c5,c30.c1023.
664660 r .high = r .low
665661 }
666662
@@ -872,8 +868,8 @@ func checkLabel(label string) error {
872868 if len (label ) != 0 {
873869 con := strings .SplitN (label , ":" , 4 )
874870 if len (con ) > 3 {
875- state .Lock ()
876- defer state .Unlock ()
871+ state .RLock ()
872+ defer state .RUnlock ()
877873 if state .mcsList [con [3 ]] {
878874 return ErrMCSAlreadyExists
879875 }
@@ -1020,12 +1016,10 @@ var loadLabels = sync.OnceValue(func() map[string]string {
10201016 // Skip comments
10211017 continue
10221018 }
1023- fields := bytes .SplitN (line , []byte {'=' }, 2 )
1024- if len ( fields ) != 2 {
1025- continue
1019+ if key , val , ok := bytes .Cut (line , []byte {'=' }); ok {
1020+ key , val = bytes . TrimSpace ( key ), bytes . TrimSpace ( val )
1021+ labels [ string ( key )] = string ( bytes . Trim ( val , `"` ))
10261022 }
1027- key , val := bytes .TrimSpace (fields [0 ]), bytes .TrimSpace (fields [1 ])
1028- labels [string (key )] = string (bytes .Trim (val , `"` ))
10291023 }
10301024
10311025 con , _ := NewContext (labels ["file" ])
0 commit comments