...
1
2
3
4 package capabilities
5
6 import (
7 "sort"
8 "strings"
9
10 "github.com/opencontainers/runc/libcontainer/configs"
11 "github.com/sirupsen/logrus"
12 "github.com/syndtr/gocapability/capability"
13 )
14
15 const allCapabilityTypes = capability.CAPS | capability.BOUNDING | capability.AMBIENT
16
17 var (
18 capabilityMap map[string]capability.Cap
19 capTypes = []capability.CapType{
20 capability.BOUNDING,
21 capability.PERMITTED,
22 capability.INHERITABLE,
23 capability.EFFECTIVE,
24 capability.AMBIENT,
25 }
26 )
27
28 func init() {
29 capabilityMap = make(map[string]capability.Cap, capability.CAP_LAST_CAP+1)
30 for _, c := range capability.List() {
31 if c > capability.CAP_LAST_CAP {
32 continue
33 }
34 capabilityMap["CAP_"+strings.ToUpper(c.String())] = c
35 }
36 }
37
38
39
40 func KnownCapabilities() []string {
41 list := capability.List()
42 res := make([]string, len(list))
43 for i, c := range list {
44 res[i] = "CAP_" + strings.ToUpper(c.String())
45 }
46 return res
47 }
48
49
50
51
52 func New(capConfig *configs.Capabilities) (*Caps, error) {
53 var (
54 err error
55 c Caps
56 )
57
58 unknownCaps := make(map[string]struct{})
59 c.caps = map[capability.CapType][]capability.Cap{
60 capability.BOUNDING: capSlice(capConfig.Bounding, unknownCaps),
61 capability.EFFECTIVE: capSlice(capConfig.Effective, unknownCaps),
62 capability.INHERITABLE: capSlice(capConfig.Inheritable, unknownCaps),
63 capability.PERMITTED: capSlice(capConfig.Permitted, unknownCaps),
64 capability.AMBIENT: capSlice(capConfig.Ambient, unknownCaps),
65 }
66 if c.pid, err = capability.NewPid2(0); err != nil {
67 return nil, err
68 }
69 if err = c.pid.Load(); err != nil {
70 return nil, err
71 }
72 if len(unknownCaps) > 0 {
73 logrus.Warn("ignoring unknown or unavailable capabilities: ", mapKeys(unknownCaps))
74 }
75 return &c, nil
76 }
77
78
79
80
81 func capSlice(caps []string, unknownCaps map[string]struct{}) []capability.Cap {
82 var out []capability.Cap
83 for _, c := range caps {
84 if v, ok := capabilityMap[c]; !ok {
85 unknownCaps[c] = struct{}{}
86 } else {
87 out = append(out, v)
88 }
89 }
90 return out
91 }
92
93
94 func mapKeys(input map[string]struct{}) []string {
95 var keys []string
96 for c := range input {
97 keys = append(keys, c)
98 }
99 sort.Strings(keys)
100 return keys
101 }
102
103
104 type Caps struct {
105 pid capability.Capabilities
106 caps map[capability.CapType][]capability.Cap
107 }
108
109
110 func (c *Caps) ApplyBoundingSet() error {
111 c.pid.Clear(capability.BOUNDING)
112 c.pid.Set(capability.BOUNDING, c.caps[capability.BOUNDING]...)
113 return c.pid.Apply(capability.BOUNDING)
114 }
115
116
117 func (c *Caps) ApplyCaps() error {
118 c.pid.Clear(allCapabilityTypes)
119 for _, g := range capTypes {
120 c.pid.Set(g, c.caps[g]...)
121 }
122 return c.pid.Apply(allCapabilityTypes)
123 }
124
View as plain text