diff options
author | OpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com> | 2020-02-14 20:13:28 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-14 20:13:28 +0100 |
commit | 7e713ff336b8dd48b6fd75b16c92e6a35579355d (patch) | |
tree | 84a9d3e1a7520aa34e8ecb1b49adf3aac5636694 /pkg/capabilities/capabilities.go | |
parent | 0668483cf04bc7089ed176fb0b6700aebf80aaf9 (diff) | |
parent | 85b7374491e842c44bec3ce5ec800794cae10295 (diff) | |
download | podman-7e713ff336b8dd48b6fd75b16c92e6a35579355d.tar.gz podman-7e713ff336b8dd48b6fd75b16c92e6a35579355d.tar.bz2 podman-7e713ff336b8dd48b6fd75b16c92e6a35579355d.zip |
Merge pull request #5209 from vrothberg/un-docker
Undocker part 1)
Diffstat (limited to 'pkg/capabilities/capabilities.go')
-rw-r--r-- | pkg/capabilities/capabilities.go | 129 |
1 files changed, 129 insertions, 0 deletions
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 +} |