Skip to content

Commit 2e79df0

Browse files
committed
SecurityContextConstraints: avoid unnecessary mutation of container capabilities.
1 parent 014f66d commit 2e79df0

File tree

2 files changed

+45
-15
lines changed

2 files changed

+45
-15
lines changed

pkg/security/securitycontextconstraints/capabilities/mustrunas.go

+11-7
Original file line numberDiff line numberDiff line change
@@ -33,31 +33,35 @@ func NewDefaultCapabilities(defaultAddCapabilities, requiredDropCapabilities, al
3333
// 1. a capabilities.Add set containing all the required adds (unless the
3434
// container specifically is dropping the cap) and container requested adds
3535
// 2. a capabilities.Drop set containing all the required drops and container requested drops
36+
//
37+
// Returns the original container capabilities if no changes are required.
3638
func (s *defaultCapabilities) Generate(pod *api.Pod, container *api.Container) (*api.Capabilities, error) {
3739
defaultAdd := makeCapSet(s.defaultAddCapabilities)
3840
requiredDrop := makeCapSet(s.requiredDropCapabilities)
3941
containerAdd := sets.NewString()
4042
containerDrop := sets.NewString()
4143

44+
var containerCapabilities *api.Capabilities
4245
if container.SecurityContext != nil && container.SecurityContext.Capabilities != nil {
46+
containerCapabilities = container.SecurityContext.Capabilities
4347
containerAdd = makeCapSet(container.SecurityContext.Capabilities.Add)
4448
containerDrop = makeCapSet(container.SecurityContext.Capabilities.Drop)
4549
}
4650

4751
// remove any default adds that the container is specifically dropping
4852
defaultAdd = defaultAdd.Difference(containerDrop)
4953

50-
combinedAdd := defaultAdd.Union(containerAdd).List()
51-
combinedDrop := requiredDrop.Union(containerDrop).List()
54+
combinedAdd := defaultAdd.Union(containerAdd)
55+
combinedDrop := requiredDrop.Union(containerDrop)
5256

53-
// nothing generated? return nil
54-
if len(combinedAdd) == 0 && len(combinedDrop) == 0 {
55-
return nil, nil
57+
// no changes? return the original capabilities
58+
if (len(combinedAdd) == len(containerAdd)) && (len(combinedDrop) == len(containerDrop)) {
59+
return containerCapabilities, nil
5660
}
5761

5862
return &api.Capabilities{
59-
Add: capabilityFromStringSlice(combinedAdd),
60-
Drop: capabilityFromStringSlice(combinedDrop),
63+
Add: capabilityFromStringSlice(combinedAdd.List()),
64+
Drop: capabilityFromStringSlice(combinedDrop.List()),
6165
}, nil
6266
}
6367

pkg/security/securitycontextconstraints/capabilities/mustrunas_test.go

+34-8
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ func TestGenerateAdds(t *testing.T) {
1919
"no required, no container requests": {
2020
expectedCaps: nil,
2121
},
22+
"no required, no container requests, non-nil": {
23+
containerCaps: &api.Capabilities{},
24+
expectedCaps: &api.Capabilities{},
25+
},
2226
"required, no container requests": {
2327
defaultAddCaps: []api.Capability{"foo"},
2428
expectedCaps: &api.Capabilities{
@@ -52,13 +56,22 @@ func TestGenerateAdds(t *testing.T) {
5256
Add: []api.Capability{"bar", "foo"},
5357
},
5458
},
59+
"generation does not mutate unnecessarily": {
60+
defaultAddCaps: []api.Capability{"foo", "bar"},
61+
containerCaps: &api.Capabilities{
62+
Add: []api.Capability{"foo", "foo", "bar", "baz"},
63+
},
64+
expectedCaps: &api.Capabilities{
65+
Add: []api.Capability{"foo", "foo", "bar", "baz"},
66+
},
67+
},
5568
"generation dedupes": {
56-
defaultAddCaps: []api.Capability{"foo", "foo", "foo", "foo"},
69+
defaultAddCaps: []api.Capability{"foo", "bar"},
5770
containerCaps: &api.Capabilities{
58-
Add: []api.Capability{"foo", "foo", "foo"},
71+
Add: []api.Capability{"foo", "baz"},
5972
},
6073
expectedCaps: &api.Capabilities{
61-
Add: []api.Capability{"foo"},
74+
Add: []api.Capability{"bar", "baz", "foo"},
6275
},
6376
},
6477
"generation is case sensitive - will not dedupe": {
@@ -109,19 +122,32 @@ func TestGenerateDrops(t *testing.T) {
109122
"no required, no container requests": {
110123
expectedCaps: nil,
111124
},
125+
"no required, no container requests, non-nil": {
126+
containerCaps: &api.Capabilities{},
127+
expectedCaps: &api.Capabilities{},
128+
},
112129
"required drops are defaulted": {
113130
requiredDropCaps: []api.Capability{"foo"},
114131
expectedCaps: &api.Capabilities{
115132
Drop: []api.Capability{"foo"},
116133
},
117134
},
118135
"required drops are defaulted when making container requests": {
119-
requiredDropCaps: []api.Capability{"foo"},
136+
requiredDropCaps: []api.Capability{"baz"},
120137
containerCaps: &api.Capabilities{
121138
Drop: []api.Capability{"foo", "bar"},
122139
},
123140
expectedCaps: &api.Capabilities{
124-
Drop: []api.Capability{"bar", "foo"},
141+
Drop: []api.Capability{"bar", "baz", "foo"},
142+
},
143+
},
144+
"required drops do not mutate unnecessarily": {
145+
requiredDropCaps: []api.Capability{"baz"},
146+
containerCaps: &api.Capabilities{
147+
Drop: []api.Capability{"foo", "bar", "baz"},
148+
},
149+
expectedCaps: &api.Capabilities{
150+
Drop: []api.Capability{"foo", "bar", "baz"},
125151
},
126152
},
127153
"can drop a required add": {
@@ -155,12 +181,12 @@ func TestGenerateDrops(t *testing.T) {
155181
},
156182
},
157183
"generation dedupes": {
158-
requiredDropCaps: []api.Capability{"bar", "bar", "bar", "bar"},
184+
requiredDropCaps: []api.Capability{"baz", "foo"},
159185
containerCaps: &api.Capabilities{
160-
Drop: []api.Capability{"bar", "bar", "bar"},
186+
Drop: []api.Capability{"bar", "foo"},
161187
},
162188
expectedCaps: &api.Capabilities{
163-
Drop: []api.Capability{"bar"},
189+
Drop: []api.Capability{"bar", "baz", "foo"},
164190
},
165191
},
166192
"generation is case sensitive - will not dedupe": {

0 commit comments

Comments
 (0)