diff options
-rw-r--r-- | go.sum | 1 | ||||
-rw-r--r-- | libpod/container_api.go | 4 | ||||
-rw-r--r-- | pkg/capabilities/capabilities.go | 129 | ||||
-rw-r--r-- | pkg/spec/security.go | 6 | ||||
-rw-r--r-- | vendor/github.com/docker/docker/oci/caps/defaults.go | 21 | ||||
-rw-r--r-- | vendor/github.com/docker/docker/oci/caps/utils.go | 169 | ||||
-rw-r--r-- | vendor/modules.txt | 1 |
7 files changed, 135 insertions, 196 deletions
@@ -616,6 +616,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v0.0.0-20190624233834-05ebafbffc79/go.mod h1:R//lfYlUuTOTfblYI3lGoAAAebUdzjvbmQsuB7Ykd90= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/libpod/container_api.go b/libpod/container_api.go index d74a14f15..d612341bc 100644 --- a/libpod/container_api.go +++ b/libpod/container_api.go @@ -11,8 +11,8 @@ import ( "github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/events" + "github.com/containers/libpod/pkg/capabilities" "github.com/containers/storage/pkg/stringid" - "github.com/docker/docker/oci/caps" "github.com/opentracing/opentracing-go" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -237,7 +237,7 @@ func (c *Container) Exec(tty, privileged bool, env map[string]string, cmd []stri } if privileged || c.config.Privileged { - capList = caps.GetAllCapabilities() + capList = capabilities.AllCapabilities() } // Generate exec session ID diff --git a/pkg/capabilities/capabilities.go b/pkg/capabilities/capabilities.go new file mode 100644 index 000000000..ea22498b8 --- /dev/null +++ b/pkg/capabilities/capabilities.go @@ -0,0 +1,129 @@ +package capabilities + +// Copyright 2013-2018 Docker, Inc. + +// NOTE: this package has been copied from github.com/docker/docker but been +// changed significantly to fit the needs of libpod. + +import ( + "strings" + + "github.com/containers/libpod/pkg/util" + "github.com/pkg/errors" + "github.com/syndtr/gocapability/capability" +) + +var ( + // Used internally and populated during init(). + capabilityList []string + + // ErrUnknownCapability is thrown when an unknown capability is processed. + ErrUnknownCapability = errors.New("unknown capability") +) + +// All is a special value used to add/drop all known capababilities. +// Useful on the CLI for `--cap-add=all` etc. +const All = "ALL" + +func init() { + last := capability.CAP_LAST_CAP + // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap + if last == capability.Cap(63) { + last = capability.CAP_BLOCK_SUSPEND + } + for _, cap := range capability.List() { + if cap > last { + continue + } + capabilityList = append(capabilityList, "CAP_"+strings.ToUpper(cap.String())) + } +} + +// AllCapabilities returns all known capabilities. +func AllCapabilities() []string { + return capabilityList +} + +// normalizeCapabilities normalizes caps by adding a "CAP_" prefix (if not yet +// present). +func normalizeCapabilities(caps []string) ([]string, error) { + normalized := make([]string, len(caps)) + for i, c := range caps { + c = strings.ToUpper(c) + if c == All { + normalized = append(normalized, c) + continue + } + if !strings.HasPrefix(c, "CAP_") { + c = "CAP_" + c + } + if !util.StringInSlice(c, capabilityList) { + return nil, errors.Wrapf(ErrUnknownCapability, "%q", c) + } + normalized[i] = c + } + return normalized, nil +} + +// ValidateCapabilities validates if caps only contains valid capabilities. +func ValidateCapabilities(caps []string) error { + for _, c := range caps { + if !util.StringInSlice(c, capabilityList) { + return errors.Wrapf(ErrUnknownCapability, "%q", c) + } + } + return nil +} + +// MergeCapabilities computes a set of capabilities by adding capapbitilities +// to or dropping them from base. +// +// Note that "ALL" will cause all known capabilities to be added/dropped but +// the ones specified to be dropped/added. +func MergeCapabilities(base, adds, drops []string) ([]string, error) { + if len(adds) == 0 && len(drops) == 0 { + // Nothing to tweak; we're done + return base, nil + } + + capDrop, err := normalizeCapabilities(drops) + if err != nil { + return nil, err + } + capAdd, err := normalizeCapabilities(adds) + if err != nil { + return nil, err + } + + // Make sure that capDrop and capAdd are distinct sets. + for _, drop := range capDrop { + if util.StringInSlice(drop, capAdd) { + return nil, errors.Errorf("capability %q cannot be dropped and added", drop) + } + } + + var caps []string + + switch { + case util.StringInSlice(All, capAdd): + // Add all capabilities except ones on capDrop + for _, c := range capabilityList { + if !util.StringInSlice(c, capDrop) { + caps = append(caps, c) + } + } + case util.StringInSlice(All, capDrop): + // "Drop" all capabilities; use what's in capAdd instead + caps = capAdd + default: + // First drop some capabilities + for _, c := range base { + if !util.StringInSlice(c, capDrop) { + caps = append(caps, c) + } + } + // Then add the list of capabilities from capAdd + caps = append(caps, capAdd...) + } + return caps, nil +} diff --git a/pkg/spec/security.go b/pkg/spec/security.go index 372fe87c6..3bad9f97a 100644 --- a/pkg/spec/security.go +++ b/pkg/spec/security.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/containers/libpod/libpod" - "github.com/docker/docker/oci/caps" + "github.com/containers/libpod/pkg/capabilities" "github.com/opencontainers/runtime-tools/generate" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" @@ -118,7 +118,7 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon if useNotRoot(user.User) { configSpec.Process.Capabilities.Bounding = caplist } - caplist, err = caps.TweakCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop, nil, false) + caplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop) if err != nil { return err } @@ -129,7 +129,7 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon configSpec.Process.Capabilities.Effective = caplist configSpec.Process.Capabilities.Ambient = caplist if useNotRoot(user.User) { - caplist, err = caps.TweakCapabilities(bounding, c.CapAdd, c.CapDrop, nil, false) + caplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop) if err != nil { return err } diff --git a/vendor/github.com/docker/docker/oci/caps/defaults.go b/vendor/github.com/docker/docker/oci/caps/defaults.go deleted file mode 100644 index 242ee5811..000000000 --- a/vendor/github.com/docker/docker/oci/caps/defaults.go +++ /dev/null @@ -1,21 +0,0 @@ -package caps // import "github.com/docker/docker/oci/caps" - -// DefaultCapabilities returns a Linux kernel default capabilities -func DefaultCapabilities() []string { - return []string{ - "CAP_CHOWN", - "CAP_DAC_OVERRIDE", - "CAP_FSETID", - "CAP_FOWNER", - "CAP_MKNOD", - "CAP_NET_RAW", - "CAP_SETGID", - "CAP_SETUID", - "CAP_SETFCAP", - "CAP_SETPCAP", - "CAP_NET_BIND_SERVICE", - "CAP_SYS_CHROOT", - "CAP_KILL", - "CAP_AUDIT_WRITE", - } -} diff --git a/vendor/github.com/docker/docker/oci/caps/utils.go b/vendor/github.com/docker/docker/oci/caps/utils.go deleted file mode 100644 index ffd3f6f50..000000000 --- a/vendor/github.com/docker/docker/oci/caps/utils.go +++ /dev/null @@ -1,169 +0,0 @@ -package caps // import "github.com/docker/docker/oci/caps" - -import ( - "fmt" - "strings" - - "github.com/docker/docker/errdefs" - "github.com/syndtr/gocapability/capability" -) - -var capabilityList Capabilities - -func init() { - last := capability.CAP_LAST_CAP - // hack for RHEL6 which has no /proc/sys/kernel/cap_last_cap - if last == capability.Cap(63) { - last = capability.CAP_BLOCK_SUSPEND - } - for _, cap := range capability.List() { - if cap > last { - continue - } - capabilityList = append(capabilityList, - &CapabilityMapping{ - Key: "CAP_" + strings.ToUpper(cap.String()), - Value: cap, - }, - ) - } -} - -type ( - // CapabilityMapping maps linux capability name to its value of capability.Cap type - // Capabilities is one of the security systems in Linux Security Module (LSM) - // framework provided by the kernel. - // For more details on capabilities, see http://man7.org/linux/man-pages/man7/capabilities.7.html - CapabilityMapping struct { - Key string `json:"key,omitempty"` - Value capability.Cap `json:"value,omitempty"` - } - // Capabilities contains all CapabilityMapping - Capabilities []*CapabilityMapping -) - -// String returns <key> of CapabilityMapping -func (c *CapabilityMapping) String() string { - return c.Key -} - -// GetCapability returns CapabilityMapping which contains specific key -func GetCapability(key string) *CapabilityMapping { - for _, capp := range capabilityList { - if capp.Key == key { - cpy := *capp - return &cpy - } - } - return nil -} - -// GetAllCapabilities returns all of the capabilities -func GetAllCapabilities() []string { - output := make([]string, len(capabilityList)) - for i, capability := range capabilityList { - output[i] = capability.String() - } - return output -} - -// inSlice tests whether a string is contained in a slice of strings or not. -func inSlice(slice []string, s string) bool { - for _, ss := range slice { - if s == ss { - return true - } - } - return false -} - -const allCapabilities = "ALL" - -// NormalizeLegacyCapabilities normalizes, and validates CapAdd/CapDrop capabilities -// by upper-casing them, and adding a CAP_ prefix (if not yet present). -// -// This function also accepts the "ALL" magic-value, that's used by CapAdd/CapDrop. -func NormalizeLegacyCapabilities(caps []string) ([]string, error) { - var normalized []string - - valids := GetAllCapabilities() - for _, c := range caps { - c = strings.ToUpper(c) - if c == allCapabilities { - normalized = append(normalized, c) - continue - } - if !strings.HasPrefix(c, "CAP_") { - c = "CAP_" + c - } - if !inSlice(valids, c) { - return nil, errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c)) - } - normalized = append(normalized, c) - } - return normalized, nil -} - -// ValidateCapabilities validates if caps only contains valid capabilities -func ValidateCapabilities(caps []string) error { - valids := GetAllCapabilities() - for _, c := range caps { - if !inSlice(valids, c) { - return errdefs.InvalidParameter(fmt.Errorf("unknown capability: %q", c)) - } - } - return nil -} - -// TweakCapabilities tweaks capabilities by adding, dropping, or overriding -// capabilities in the basics capabilities list. -func TweakCapabilities(basics, adds, drops, capabilities []string, privileged bool) ([]string, error) { - switch { - case privileged: - // Privileged containers get all capabilities - return GetAllCapabilities(), nil - case capabilities != nil: - // Use custom set of capabilities - if err := ValidateCapabilities(capabilities); err != nil { - return nil, err - } - return capabilities, nil - case len(adds) == 0 && len(drops) == 0: - // Nothing to tweak; we're done - return basics, nil - } - - capDrop, err := NormalizeLegacyCapabilities(drops) - if err != nil { - return nil, err - } - capAdd, err := NormalizeLegacyCapabilities(adds) - if err != nil { - return nil, err - } - - var caps []string - - switch { - case inSlice(capAdd, allCapabilities): - // Add all capabilities except ones on capDrop - for _, c := range GetAllCapabilities() { - if !inSlice(capDrop, c) { - caps = append(caps, c) - } - } - case inSlice(capDrop, allCapabilities): - // "Drop" all capabilities; use what's in capAdd instead - caps = capAdd - default: - // First drop some capabilities - for _, c := range basics { - if !inSlice(capDrop, c) { - caps = append(caps, c) - } - } - // Then add the list of capabilities from capAdd - caps = append(caps, capAdd...) - } - return caps, nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index 73bca1ef8..3c03fbdfb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -227,7 +227,6 @@ github.com/docker/docker/api/types/versions github.com/docker/docker/api/types/volume github.com/docker/docker/client github.com/docker/docker/errdefs -github.com/docker/docker/oci/caps github.com/docker/docker/pkg/archive github.com/docker/docker/pkg/fileutils github.com/docker/docker/pkg/homedir |