@@ -25,29 +25,31 @@ import (
2525 "strings"
2626
2727 "github.com/pkg/errors"
28- "github.com/syndtr/gocapability/capability"
2928)
3029
31- // FromUint64 parses an integer into string slice like
30+ // FromNumber returns a cap string like "CAP_SYS_ADMIN"
31+ // that corresponds to the given number like 21.
32+ //
33+ // FromNumber returns an empty string for unknown cap number.
34+ func FromNumber (num int ) string {
35+ if num < 0 || num > len (capsLatest )- 1 {
36+ return ""
37+ }
38+ return capsLatest [num ]
39+ }
40+
41+ // FromBitmap parses an uint64 bitmap into string slice like
3242// []{"CAP_SYS_ADMIN", ...}.
3343//
3444// Unknown cap numbers are returned as []int.
35- func FromUint64 (v uint64 ) ([]string , []int ) {
45+ func FromBitmap (v uint64 ) ([]string , []int ) {
3646 var (
3747 res []string
3848 unknown []int
3949 )
40- knownList := capability .List ()
41- known := make (map [string ]struct {}, len (knownList ))
42- for _ , f := range knownList {
43- known [f .String ()] = struct {}{}
44- }
4550 for i := 0 ; i <= 63 ; i ++ {
4651 if b := (v >> i ) & 0x1 ; b == 0x1 {
47- c := capability .Cap (i )
48- sRaw := c .String ()
49- if _ , ok := known [sRaw ]; ok {
50- s := "CAP_" + strings .ToUpper (sRaw )
52+ if s := FromNumber (i ); s != "" {
5153 res = append (res , s )
5254 } else {
5355 unknown = append (unknown , i )
@@ -57,9 +59,25 @@ func FromUint64(v uint64) ([]string, []int) {
5759 return res , unknown
5860}
5961
60- // ParseProcPIDStatus returns uint64 value from /proc/<PID>/status file
61- func ParseProcPIDStatus (r io.Reader ) (map [capability.CapType ]uint64 , error ) {
62- res := make (map [capability.CapType ]uint64 )
62+ // Type is the type of capability
63+ type Type int
64+
65+ const (
66+ // Effective is CapEff
67+ Effective Type = 1 << iota
68+ // Effective is CapPrm
69+ Permitted
70+ // Inheritable is CapInh
71+ Inheritable
72+ // Bounding is CapBnd
73+ Bounding
74+ // Ambient is CapAmb
75+ Ambient
76+ )
77+
78+ // ParseProcPIDStatus returns uint64 bitmap value from /proc/<PID>/status file
79+ func ParseProcPIDStatus (r io.Reader ) (map [Type ]uint64 , error ) {
80+ res := make (map [Type ]uint64 )
6381 scanner := bufio .NewScanner (r )
6482 for scanner .Scan () {
6583 line := scanner .Text ()
@@ -77,15 +95,15 @@ func ParseProcPIDStatus(r io.Reader) (map[capability.CapType]uint64, error) {
7795 }
7896 switch k {
7997 case "CapInh" :
80- res [capability . INHERITABLE ] = ui64
98+ res [Inheritable ] = ui64
8199 case "CapPrm" :
82- res [capability . PERMITTED ] = ui64
100+ res [Permitted ] = ui64
83101 case "CapEff" :
84- res [capability . EFFECTIVE ] = ui64
102+ res [Effective ] = ui64
85103 case "CapBnd" :
86- res [capability . BOUNDING ] = ui64
104+ res [Bounding ] = ui64
87105 case "CapAmb" :
88- res [capability . AMBIENT ] = ui64
106+ res [Ambient ] = ui64
89107 }
90108 }
91109 }
@@ -112,8 +130,8 @@ func Current() ([]string, error) {
112130 if err != nil {
113131 return nil , err
114132 }
115- capEff := caps [capability . EFFECTIVE ]
116- names , _ := FromUint64 (capEff )
133+ capEff := caps [Effective ]
134+ names , _ := FromBitmap (capEff )
117135 return names , nil
118136}
119137
@@ -163,10 +181,12 @@ var (
163181 // caps58 is the caps of kernel 5.8 (40 entries)
164182 caps58 = append (caps316 , []string {"CAP_PERFMON" , "CAP_BPF" }... )
165183 // caps59 is the caps of kernel 5.9 (41 entries)
166- caps59 = append (caps58 , "CAP_CHECKPOINT_RESTORE" )
184+ caps59 = append (caps58 , "CAP_CHECKPOINT_RESTORE" )
185+ capsLatest = caps59
167186)
168187
169- // Known returns the known cap strings as of kernel 5.9
188+ // Known returns the known cap strings of the latest kernel.
189+ // The current latest kernel is 5.9.
170190func Known () []string {
171- return caps59
191+ return capsLatest
172192}
0 commit comments