@@ -3,29 +3,43 @@ package capabilities
33import (
44 "fmt"
55 "strings"
6+ "sync"
67
7- "github.com/syndtr/gocapability /capability"
8+ "github.com/moby/sys /capability"
89)
910
10- // CapValid checks whether a capability is valid
11+ // CapValid checks whether a capability is valid. If hostSpecific is set,
12+ // it also checks that the capability is supported on the current host.
1113func CapValid (c string , hostSpecific bool ) error {
12- isValid := false
13-
1414 if ! strings .HasPrefix (c , "CAP_" ) {
1515 return fmt .Errorf ("capability %s must start with CAP_" , c )
1616 }
17- for _ , cap := range capability .List () {
18- if c == fmt .Sprintf ("CAP_%s" , strings .ToUpper (cap .String ())) {
19- if hostSpecific && cap > LastCap () {
20- return fmt .Errorf ("%s is not supported on the current host" , c )
21- }
22- isValid = true
23- break
24- }
25- }
2617
27- if ! isValid {
18+ if _ , ok := knownCaps ()[ c ]; ! ok {
2819 return fmt .Errorf ("invalid capability: %s" , c )
2920 }
21+ if ! hostSpecific {
22+ return nil
23+ }
24+ if _ , ok := supportedCaps ()[c ]; ! ok {
25+ return fmt .Errorf ("%s is not supported on the current host" , c )
26+ }
3027 return nil
3128}
29+
30+ func capSet (list []capability.Cap ) map [string ]struct {} {
31+ m := make (map [string ]struct {}, len (list ))
32+ for _ , c := range list {
33+ m ["CAP_" + strings .ToUpper (c .String ())] = struct {}{}
34+ }
35+ return m
36+ }
37+
38+ var knownCaps = sync .OnceValue (func () map [string ]struct {} {
39+ return capSet (capability .ListKnown ())
40+ })
41+
42+ var supportedCaps = sync .OnceValue (func () map [string ]struct {} {
43+ list , _ := capability .ListSupported ()
44+ return capSet (list )
45+ })
0 commit comments