Support for dropping inheritable capabilities
Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
parent
3c6ddee128
commit
d0527e2283
@ -943,6 +943,11 @@ func WithCapabilities(caps []string) SpecOpts {
|
||||
s.Process.Capabilities.Bounding = caps
|
||||
s.Process.Capabilities.Effective = caps
|
||||
s.Process.Capabilities.Permitted = caps
|
||||
if len(caps) == 0 {
|
||||
s.Process.Capabilities.Inheritable = nil
|
||||
} else if len(s.Process.Capabilities.Inheritable) > 0 {
|
||||
filterCaps(&s.Process.Capabilities.Inheritable, caps)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -968,6 +973,16 @@ func removeCap(caps *[]string, s string) {
|
||||
*caps = newcaps
|
||||
}
|
||||
|
||||
func filterCaps(caps *[]string, filters []string) {
|
||||
var newcaps []string
|
||||
for _, c := range *caps {
|
||||
if capsContain(filters, c) {
|
||||
newcaps = append(newcaps, c)
|
||||
}
|
||||
}
|
||||
*caps = newcaps
|
||||
}
|
||||
|
||||
// WithAddedCapabilities adds the provided capabilities
|
||||
func WithAddedCapabilities(caps []string) SpecOpts {
|
||||
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||
@ -996,6 +1011,7 @@ func WithDroppedCapabilities(caps []string) SpecOpts {
|
||||
&s.Process.Capabilities.Bounding,
|
||||
&s.Process.Capabilities.Effective,
|
||||
&s.Process.Capabilities.Permitted,
|
||||
&s.Process.Capabilities.Inheritable,
|
||||
} {
|
||||
removeCap(cl, c)
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/containerd/containerd/containers"
|
||||
"github.com/containerd/containerd/pkg/cap"
|
||||
"github.com/containerd/containerd/pkg/testutil"
|
||||
"github.com/containerd/continuity/fs/fstest"
|
||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||
@ -216,6 +217,91 @@ sys:x:3:root,bin,adm
|
||||
}
|
||||
}
|
||||
|
||||
// withAllKnownCaps sets all known capabilities.
|
||||
// This function differs from the exported function
|
||||
// by also setting inheritable capabilities.
|
||||
func withAllKnownCaps(s *specs.Spec) error {
|
||||
caps := cap.Known()
|
||||
if err := WithCapabilities(caps)(context.Background(), nil, nil, s); err != nil {
|
||||
return err
|
||||
}
|
||||
s.Process.Capabilities.Inheritable = caps
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestSetCaps(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var s specs.Spec
|
||||
|
||||
// Add base set of capabilities
|
||||
if err := WithCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, cl := range [][]string{
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
} {
|
||||
if !capsContain(cl, "CAP_CHOWN") {
|
||||
t.Errorf("cap list %d does not contain added cap", i)
|
||||
}
|
||||
if len(cl) != 1 {
|
||||
t.Errorf("cap list %d does not have only 1 cap", i)
|
||||
}
|
||||
}
|
||||
if len(s.Process.Capabilities.Inheritable) != 0 {
|
||||
t.Errorf("inheritable cap list is not empty")
|
||||
}
|
||||
|
||||
// Add all caps then overwrite with single cap
|
||||
if err := withAllKnownCaps(&s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := WithCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, cl := range [][]string{
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
s.Process.Capabilities.Inheritable,
|
||||
} {
|
||||
if !capsContain(cl, "CAP_CHOWN") {
|
||||
t.Errorf("cap list %d does not contain added cap", i)
|
||||
}
|
||||
if len(cl) != 1 {
|
||||
t.Errorf("cap list %d does not have only 1 cap", i)
|
||||
}
|
||||
}
|
||||
|
||||
// Add all caps, drop single cap, then overwrite with single cap
|
||||
if err := withAllKnownCaps(&s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := WithDroppedCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := WithCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, cl := range [][]string{
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
} {
|
||||
if !capsContain(cl, "CAP_CHOWN") {
|
||||
t.Errorf("cap list %d does not contain added cap", i)
|
||||
}
|
||||
if len(cl) != 1 {
|
||||
t.Errorf("cap list %d does not have only 1 cap", i)
|
||||
}
|
||||
}
|
||||
if len(s.Process.Capabilities.Inheritable) != 0 {
|
||||
t.Errorf("inheritable cap list is not empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAddCaps(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@ -233,6 +319,9 @@ func TestAddCaps(t *testing.T) {
|
||||
t.Errorf("cap list %d does not contain added cap", i)
|
||||
}
|
||||
}
|
||||
if len(s.Process.Capabilities.Inheritable) != 0 {
|
||||
t.Errorf("inheritable cap list is not empty")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDropCaps(t *testing.T) {
|
||||
@ -240,7 +329,7 @@ func TestDropCaps(t *testing.T) {
|
||||
|
||||
var s specs.Spec
|
||||
|
||||
if err := WithAllKnownCapabilities(context.Background(), nil, nil, &s); err != nil {
|
||||
if err := withAllKnownCaps(&s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := WithDroppedCapabilities([]string{"CAP_CHOWN"})(context.Background(), nil, nil, &s); err != nil {
|
||||
@ -251,6 +340,7 @@ func TestDropCaps(t *testing.T) {
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
s.Process.Capabilities.Inheritable,
|
||||
} {
|
||||
if capsContain(cl, "CAP_CHOWN") {
|
||||
t.Errorf("cap list %d contains dropped cap", i)
|
||||
@ -258,7 +348,7 @@ func TestDropCaps(t *testing.T) {
|
||||
}
|
||||
|
||||
// Add all capabilities back and drop a different cap.
|
||||
if err := WithAllKnownCapabilities(context.Background(), nil, nil, &s); err != nil {
|
||||
if err := withAllKnownCaps(&s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := WithDroppedCapabilities([]string{"CAP_FOWNER"})(context.Background(), nil, nil, &s); err != nil {
|
||||
@ -269,6 +359,7 @@ func TestDropCaps(t *testing.T) {
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
s.Process.Capabilities.Inheritable,
|
||||
} {
|
||||
if capsContain(cl, "CAP_FOWNER") {
|
||||
t.Errorf("cap list %d contains dropped cap", i)
|
||||
@ -289,6 +380,25 @@ func TestDropCaps(t *testing.T) {
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
s.Process.Capabilities.Inheritable,
|
||||
} {
|
||||
if len(cl) != 0 {
|
||||
t.Errorf("cap list %d is not empty", i)
|
||||
}
|
||||
}
|
||||
|
||||
// Add all capabilities back and drop all
|
||||
if err := withAllKnownCaps(&s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := WithCapabilities(nil)(context.Background(), nil, nil, &s); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, cl := range [][]string{
|
||||
s.Process.Capabilities.Bounding,
|
||||
s.Process.Capabilities.Effective,
|
||||
s.Process.Capabilities.Permitted,
|
||||
s.Process.Capabilities.Inheritable,
|
||||
} {
|
||||
if len(cl) != 0 {
|
||||
t.Errorf("cap list %d is not empty", i)
|
||||
|
Loading…
Reference in New Issue
Block a user