Add additional capability handling opts
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
ef45e4f021
commit
bdd84abf05
@ -33,7 +33,7 @@ import (
|
|||||||
"github.com/containerd/containerd/namespaces"
|
"github.com/containerd/containerd/namespaces"
|
||||||
"github.com/containerd/containerd/platforms"
|
"github.com/containerd/containerd/platforms"
|
||||||
"github.com/containerd/continuity/fs"
|
"github.com/containerd/continuity/fs"
|
||||||
"github.com/opencontainers/image-spec/specs-go/v1"
|
v1 "github.com/opencontainers/image-spec/specs-go/v1"
|
||||||
"github.com/opencontainers/runc/libcontainer/user"
|
"github.com/opencontainers/runc/libcontainer/user"
|
||||||
specs "github.com/opencontainers/runtime-spec/specs-go"
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
@ -741,9 +741,11 @@ func WithCapabilities(caps []string) SpecOpts {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// WithAllCapabilities sets all linux capabilities for the process
|
// WithAllCapabilities sets all linux capabilities for the process
|
||||||
var WithAllCapabilities = WithCapabilities(getAllCapabilities())
|
var WithAllCapabilities = WithCapabilities(GetAllCapabilities())
|
||||||
|
|
||||||
func getAllCapabilities() []string {
|
// GetAllCapabilities returns all caps up to CAP_LAST_CAP
|
||||||
|
// or CAP_BLOCK_SUSPEND on RHEL6
|
||||||
|
func GetAllCapabilities() []string {
|
||||||
last := capability.CAP_LAST_CAP
|
last := capability.CAP_LAST_CAP
|
||||||
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
// hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap
|
||||||
if last == capability.Cap(63) {
|
if last == capability.Cap(63) {
|
||||||
@ -759,6 +761,61 @@ func getAllCapabilities() []string {
|
|||||||
return caps
|
return caps
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func capsContain(caps []string, s string) bool {
|
||||||
|
for _, c := range caps {
|
||||||
|
if c == s {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func removeCap(caps *[]string, s string) {
|
||||||
|
for i, c := range *caps {
|
||||||
|
if c == s {
|
||||||
|
*caps = append((*caps)[:i], (*caps)[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithAddedCapabilities adds the provided capabilities
|
||||||
|
func WithAddedCapabilities(caps []string) SpecOpts {
|
||||||
|
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||||
|
setCapabilities(s)
|
||||||
|
for _, c := range caps {
|
||||||
|
for _, cl := range []*[]string{
|
||||||
|
&s.Process.Capabilities.Bounding,
|
||||||
|
&s.Process.Capabilities.Effective,
|
||||||
|
&s.Process.Capabilities.Permitted,
|
||||||
|
&s.Process.Capabilities.Inheritable,
|
||||||
|
} {
|
||||||
|
if !capsContain(*cl, c) {
|
||||||
|
*cl = append(*cl, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// WithDroppedCapabilities removes the provided capabilities
|
||||||
|
func WithDroppedCapabilities(caps []string) SpecOpts {
|
||||||
|
return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error {
|
||||||
|
setCapabilities(s)
|
||||||
|
for _, c := range caps {
|
||||||
|
for _, cl := range []*[]string{
|
||||||
|
&s.Process.Capabilities.Bounding,
|
||||||
|
&s.Process.Capabilities.Effective,
|
||||||
|
&s.Process.Capabilities.Permitted,
|
||||||
|
&s.Process.Capabilities.Inheritable,
|
||||||
|
} {
|
||||||
|
removeCap(cl, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithAmbientCapabilities set the Linux ambient capabilities for the process
|
// WithAmbientCapabilities set the Linux ambient capabilities for the process
|
||||||
// Ambient capabilities should only be set for non-root users or the caller should
|
// Ambient capabilities should only be set for non-root users or the caller should
|
||||||
// understand how these capabilities are used and set
|
// understand how these capabilities are used and set
|
||||||
|
@ -422,3 +422,47 @@ func TestWithImageConfigArgs(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAddCaps(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var s specs.Spec
|
||||||
|
|
||||||
|
if err := WithAddedCapabilities([]string{"CAP_CHOWN"})(nil, 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDropCaps(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
var s specs.Spec
|
||||||
|
|
||||||
|
if err := WithAllCapabilities(nil, nil, nil, &s); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := WithDroppedCapabilities([]string{"CAP_CHOWN"})(nil, 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 contains dropped cap", i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user