summaryrefslogtreecommitdiff
path: root/pkg/spec
diff options
context:
space:
mode:
authorOpenShift Merge Robot <openshift-merge-robot@users.noreply.github.com>2020-03-03 14:48:10 +0100
committerGitHub <noreply@github.com>2020-03-03 14:48:10 +0100
commit3bc5f431d4df9724501a42a68e333f7e98a0b0cf (patch)
tree1f17afda2b289133dc4feaec4d8fb495c43372f2 /pkg/spec
parent34baea814ba6af58e7f7b65622fd0fb7b838fbf7 (diff)
parentf678b3fcf13d78cf45ea4fdb7f9f0937773b8371 (diff)
downloadpodman-3bc5f431d4df9724501a42a68e333f7e98a0b0cf.tar.gz
podman-3bc5f431d4df9724501a42a68e333f7e98a0b0cf.tar.bz2
podman-3bc5f431d4df9724501a42a68e333f7e98a0b0cf.zip
Merge pull request #5206 from rhatdan/capabilities
Allow devs to set labels in container images for default capabilities.
Diffstat (limited to 'pkg/spec')
-rw-r--r--pkg/spec/createconfig.go1
-rw-r--r--pkg/spec/security.go45
-rw-r--r--pkg/spec/spec.go14
3 files changed, 49 insertions, 11 deletions
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 02678a687..1d9633bb3 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -112,6 +112,7 @@ type NetworkConfig struct {
type SecurityConfig struct {
CapAdd []string // cap-add
CapDrop []string // cap-drop
+ CapRequired []string // cap-required
LabelOpts []string //SecurityOpts
NoNewPrivs bool //SecurityOpts
ApparmorProfile string //SecurityOpts
diff --git a/pkg/spec/security.go b/pkg/spec/security.go
index 3bad9f97a..ca025eb3e 100644
--- a/pkg/spec/security.go
+++ b/pkg/spec/security.go
@@ -4,11 +4,13 @@ import (
"fmt"
"strings"
+ "github.com/containers/common/pkg/capabilities"
"github.com/containers/libpod/libpod"
- "github.com/containers/libpod/pkg/capabilities"
+ "github.com/containers/libpod/pkg/util"
"github.com/opencontainers/runtime-tools/generate"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
+ "github.com/sirupsen/logrus"
)
// ToCreateOptions convert the SecurityConfig to a slice of container create
@@ -113,28 +115,49 @@ func (c *SecurityConfig) ConfigureGenerator(g *generate.Generator, user *UserCon
configSpec := g.Config
var err error
- var caplist []string
+ var defaultCaplist []string
bounding := configSpec.Process.Capabilities.Bounding
if useNotRoot(user.User) {
- configSpec.Process.Capabilities.Bounding = caplist
+ configSpec.Process.Capabilities.Bounding = defaultCaplist
}
- caplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop)
+ defaultCaplist, err = capabilities.MergeCapabilities(configSpec.Process.Capabilities.Bounding, c.CapAdd, c.CapDrop)
if err != nil {
return err
}
- configSpec.Process.Capabilities.Bounding = caplist
- configSpec.Process.Capabilities.Permitted = caplist
- configSpec.Process.Capabilities.Inheritable = caplist
- configSpec.Process.Capabilities.Effective = caplist
- configSpec.Process.Capabilities.Ambient = caplist
+ privCapRequired := []string{}
+
+ if !c.Privileged && len(c.CapRequired) > 0 {
+ // Pass CapRequired in CapAdd field to normalize capabilties names
+ capRequired, err := capabilities.MergeCapabilities(nil, c.CapRequired, nil)
+ if err != nil {
+ logrus.Errorf("capabilties requested by user or image are not valid: %q", strings.Join(c.CapRequired, ","))
+ } else {
+ // Verify all capRequiered are in the defaultCapList
+ for _, cap := range capRequired {
+ if !util.StringInSlice(cap, defaultCaplist) {
+ privCapRequired = append(privCapRequired, cap)
+ }
+ }
+ }
+ if len(privCapRequired) == 0 {
+ defaultCaplist = capRequired
+ } else {
+ logrus.Errorf("capabilties requested by user or image are not allowed by default: %q", strings.Join(privCapRequired, ","))
+ }
+ }
+ configSpec.Process.Capabilities.Bounding = defaultCaplist
+ configSpec.Process.Capabilities.Permitted = defaultCaplist
+ configSpec.Process.Capabilities.Inheritable = defaultCaplist
+ configSpec.Process.Capabilities.Effective = defaultCaplist
+ configSpec.Process.Capabilities.Ambient = defaultCaplist
if useNotRoot(user.User) {
- caplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop)
+ defaultCaplist, err = capabilities.MergeCapabilities(bounding, c.CapAdd, c.CapDrop)
if err != nil {
return err
}
}
- configSpec.Process.Capabilities.Bounding = caplist
+ configSpec.Process.Capabilities.Bounding = defaultCaplist
// HANDLE SECCOMP
if c.SeccompProfilePath != "unconfined" {
diff --git a/pkg/spec/spec.go b/pkg/spec/spec.go
index 77f8bc657..8f0630b85 100644
--- a/pkg/spec/spec.go
+++ b/pkg/spec/spec.go
@@ -3,6 +3,7 @@ package createconfig
import (
"strings"
+ "github.com/containers/common/pkg/capabilities"
"github.com/containers/libpod/libpod"
libpodconfig "github.com/containers/libpod/libpod/config"
"github.com/containers/libpod/libpod/define"
@@ -10,6 +11,7 @@ import (
"github.com/containers/libpod/pkg/env"
"github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/sysinfo"
+ "github.com/containers/libpod/pkg/util"
"github.com/docker/go-units"
"github.com/opencontainers/runc/libcontainer/user"
spec "github.com/opencontainers/runtime-spec/specs-go"
@@ -330,6 +332,18 @@ func (config *CreateConfig) createConfigToOCISpec(runtime *libpod.Runtime, userM
}
configSpec := g.Config
+ // If the container image specifies an label with a
+ // capabilities.ContainerImageLabel then split the comma separated list
+ // of capabilities and record them. This list indicates the only
+ // capabilities, required to run the container.
+ var capRequired []string
+ for key, val := range config.Labels {
+ if util.StringInSlice(key, capabilities.ContainerImageLabels) {
+ capRequired = strings.Split(val, ",")
+ }
+ }
+ config.Security.CapRequired = capRequired
+
if err := config.Security.ConfigureGenerator(&g, &config.User); err != nil {
return nil, err
}