Skip to content

Commit b06e353

Browse files
authored
Merge pull request containerd#10469 from dims/automated-cherry-pick-of-#8356-upstream-release-1.7
[release/1.7] Support for dropping inheritable capabilities
2 parents 923bb1f + ce65228 commit b06e353

File tree

2 files changed

+128
-2
lines changed

2 files changed

+128
-2
lines changed

oci/spec_opts.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,11 @@ func WithCapabilities(caps []string) SpecOpts {
955955
s.Process.Capabilities.Bounding = caps
956956
s.Process.Capabilities.Effective = caps
957957
s.Process.Capabilities.Permitted = caps
958+
if len(caps) == 0 {
959+
s.Process.Capabilities.Inheritable = nil
960+
} else if len(s.Process.Capabilities.Inheritable) > 0 {
961+
filterCaps(&s.Process.Capabilities.Inheritable, caps)
962+
}
958963

959964
return nil
960965
}
@@ -980,6 +985,16 @@ func removeCap(caps *[]string, s string) {
980985
*caps = newcaps
981986
}
982987

988+
func filterCaps(caps *[]string, filters []string) {
989+
var newcaps []string
990+
for _, c := range *caps {
991+
if capsContain(filters, c) {
992+
newcaps = append(newcaps, c)
993+
}
994+
}
995+
*caps = newcaps
996+
}
997+
983998
// WithAddedCapabilities adds the provided capabilities
984999
func WithAddedCapabilities(caps []string) SpecOpts {
9851000
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
@@ -1008,6 +1023,7 @@ func WithDroppedCapabilities(caps []string) SpecOpts {
10081023
&s.Process.Capabilities.Bounding,
10091024
&s.Process.Capabilities.Effective,
10101025
&s.Process.Capabilities.Permitted,
1026+
&s.Process.Capabilities.Inheritable,
10111027
} {
10121028
removeCap(cl, c)
10131029
}

oci/spec_opts_linux_test.go

Lines changed: 112 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"testing"
2525

2626
"github.com/containerd/containerd/containers"
27+
"github.com/containerd/containerd/pkg/cap"
2728
"github.com/containerd/containerd/pkg/testutil"
2829
"github.com/containerd/continuity/fs/fstest"
2930
specs "github.com/opencontainers/runtime-spec/specs-go"
@@ -216,6 +217,91 @@ sys:x:3:root,bin,adm
216217
}
217218
}
218219

220+
// withAllKnownCaps sets all known capabilities.
221+
// This function differs from the exported function
222+
// by also setting inheritable capabilities.
223+
func withAllKnownCaps(s *specs.Spec) error {
224+
caps := cap.Known()
225+
if err := WithCapabilities(caps)(context.Background(), nil, nil, s); err != nil {
226+
return err
227+
}
228+
s.Process.Capabilities.Inheritable = caps
229+
return nil
230+
}
231+
232+
func TestSetCaps(t *testing.T) {
233+
t.Parallel()
234+
235+
var s specs.Spec
236+
237+
// Add base set of capabilities
238+
if err := WithCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
239+
t.Fatal(err)
240+
}
241+
for i, cl := range [][]string{
242+
s.Process.Capabilities.Bounding,
243+
s.Process.Capabilities.Effective,
244+
s.Process.Capabilities.Permitted,
245+
} {
246+
if !capsContain(cl, "CAP_CHOWN") {
247+
t.Errorf("cap list %d does not contain added cap", i)
248+
}
249+
if len(cl) != 1 {
250+
t.Errorf("cap list %d does not have only 1 cap", i)
251+
}
252+
}
253+
if len(s.Process.Capabilities.Inheritable) != 0 {
254+
t.Errorf("inheritable cap list is not empty")
255+
}
256+
257+
// Add all caps then overwrite with single cap
258+
if err := withAllKnownCaps(&s); err != nil {
259+
t.Fatal(err)
260+
}
261+
if err := WithCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
262+
t.Fatal(err)
263+
}
264+
for i, cl := range [][]string{
265+
s.Process.Capabilities.Bounding,
266+
s.Process.Capabilities.Effective,
267+
s.Process.Capabilities.Permitted,
268+
s.Process.Capabilities.Inheritable,
269+
} {
270+
if !capsContain(cl, "CAP_CHOWN") {
271+
t.Errorf("cap list %d does not contain added cap", i)
272+
}
273+
if len(cl) != 1 {
274+
t.Errorf("cap list %d does not have only 1 cap", i)
275+
}
276+
}
277+
278+
// Add all caps, drop single cap, then overwrite with single cap
279+
if err := withAllKnownCaps(&s); err != nil {
280+
t.Fatal(err)
281+
}
282+
if err := WithDroppedCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
283+
t.Fatal(err)
284+
}
285+
if err := WithCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
286+
t.Fatal(err)
287+
}
288+
for i, cl := range [][]string{
289+
s.Process.Capabilities.Bounding,
290+
s.Process.Capabilities.Effective,
291+
s.Process.Capabilities.Permitted,
292+
} {
293+
if !capsContain(cl, "CAP_CHOWN") {
294+
t.Errorf("cap list %d does not contain added cap", i)
295+
}
296+
if len(cl) != 1 {
297+
t.Errorf("cap list %d does not have only 1 cap", i)
298+
}
299+
}
300+
if len(s.Process.Capabilities.Inheritable) != 0 {
301+
t.Errorf("inheritable cap list is not empty")
302+
}
303+
}
304+
219305
func TestAddCaps(t *testing.T) {
220306
t.Parallel()
221307

@@ -233,14 +319,17 @@ func TestAddCaps(t *testing.T) {
233319
t.Errorf("cap list %d does not contain added cap", i)
234320
}
235321
}
322+
if len(s.Process.Capabilities.Inheritable) != 0 {
323+
t.Errorf("inheritable cap list is not empty")
324+
}
236325
}
237326

238327
func TestDropCaps(t *testing.T) {
239328
t.Parallel()
240329

241330
var s specs.Spec
242331

243-
if err := WithAllKnownCapabilities(context.Background(), nil, nil, &s); err != nil {
332+
if err := withAllKnownCaps(&s); err != nil {
244333
t.Fatal(err)
245334
}
246335
if err := WithDroppedCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
@@ -251,14 +340,15 @@ func TestDropCaps(t *testing.T) {
251340
s.Process.Capabilities.Bounding,
252341
s.Process.Capabilities.Effective,
253342
s.Process.Capabilities.Permitted,
343+
s.Process.Capabilities.Inheritable,
254344
} {
255345
if capsContain(cl, "CAP_CHOWN") {
256346
t.Errorf("cap list %d contains dropped cap", i)
257347
}
258348
}
259349

260350
// Add all capabilities back and drop a different cap.
261-
if err := WithAllKnownCapabilities(context.Background(), nil, nil, &s); err != nil {
351+
if err := withAllKnownCaps(&s); err != nil {
262352
t.Fatal(err)
263353
}
264354
if err := WithDroppedCapabilities([]string{"CAP_FOWNER"})(context.Background(), nil, nil, &s); err != nil {
@@ -269,6 +359,7 @@ func TestDropCaps(t *testing.T) {
269359
s.Process.Capabilities.Bounding,
270360
s.Process.Capabilities.Effective,
271361
s.Process.Capabilities.Permitted,
362+
s.Process.Capabilities.Inheritable,
272363
} {
273364
if capsContain(cl, "CAP_FOWNER") {
274365
t.Errorf("cap list %d contains dropped cap", i)
@@ -289,6 +380,25 @@ func TestDropCaps(t *testing.T) {
289380
s.Process.Capabilities.Bounding,
290381
s.Process.Capabilities.Effective,
291382
s.Process.Capabilities.Permitted,
383+
s.Process.Capabilities.Inheritable,
384+
} {
385+
if len(cl) != 0 {
386+
t.Errorf("cap list %d is not empty", i)
387+
}
388+
}
389+
390+
// Add all capabilities back and drop all
391+
if err := withAllKnownCaps(&s); err != nil {
392+
t.Fatal(err)
393+
}
394+
if err := WithCapabilities(nil)(context.Background(), nil, nil, &s); err != nil {
395+
t.Fatal(err)
396+
}
397+
for i, cl := range [][]string{
398+
s.Process.Capabilities.Bounding,
399+
s.Process.Capabilities.Effective,
400+
s.Process.Capabilities.Permitted,
401+
s.Process.Capabilities.Inheritable,
292402
} {
293403
if len(cl) != 0 {
294404
t.Errorf("cap list %d is not empty", i)

0 commit comments

Comments
 (0)