aboutsummaryrefslogtreecommitdiff
path: root/pkg/spec
diff options
context:
space:
mode:
authorValentin Rothberg <rothberg@redhat.com>2020-01-07 16:48:07 +0100
committerValentin Rothberg <rothberg@redhat.com>2020-01-09 17:57:58 +0100
commitf3f4c54f2abc341cee1e7b83e9538d91a3c627e3 (patch)
tree9c7174550c1071cd1b5ba98484f32e6169cee1ed /pkg/spec
parent7ccf412f7068acac16aa5aecf059df19c239f7cc (diff)
downloadpodman-f3f4c54f2abc341cee1e7b83e9538d91a3c627e3.tar.gz
podman-f3f4c54f2abc341cee1e7b83e9538d91a3c627e3.tar.bz2
podman-f3f4c54f2abc341cee1e7b83e9538d91a3c627e3.zip
policy for seccomp-profile selection
Implement a policy for selecting a seccomp profile. In addition to the default behaviour (default profile unless --security-opt seccomp is set) add a second policy doing a lookup in the image annotation. If the image has the "io.containers.seccomp.profile" set its value will be interpreted as a seccomp profile. The policy can be selected via the new --seccomp-policy CLI flag. Once the containers.conf support is merged into libpod, we can add an option there as well. Note that this feature is marked as experimental and may change in the future. Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
Diffstat (limited to 'pkg/spec')
-rw-r--r--pkg/spec/config_linux_cgo.go12
-rw-r--r--pkg/spec/createconfig.go67
2 files changed, 68 insertions, 11 deletions
diff --git a/pkg/spec/config_linux_cgo.go b/pkg/spec/config_linux_cgo.go
index c47156456..ae83c9d52 100644
--- a/pkg/spec/config_linux_cgo.go
+++ b/pkg/spec/config_linux_cgo.go
@@ -8,13 +8,24 @@ import (
spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors"
seccomp "github.com/seccomp/containers-golang"
+ "github.com/sirupsen/logrus"
)
func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.LinuxSeccomp, error) {
var seccompConfig *spec.LinuxSeccomp
var err error
+ if config.SeccompPolicy == SeccompPolicyImage && config.SeccompProfileFromImage != "" {
+ logrus.Debug("Loading seccomp profile from the security config")
+ seccompConfig, err = seccomp.LoadProfile(config.SeccompProfileFromImage, configSpec)
+ if err != nil {
+ return nil, errors.Wrap(err, "loading seccomp profile failed")
+ }
+ return seccompConfig, nil
+ }
+
if config.SeccompProfilePath != "" {
+ logrus.Debugf("Loading seccomp profile from %q", config.SeccompProfilePath)
seccompProfile, err := ioutil.ReadFile(config.SeccompProfilePath)
if err != nil {
return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
@@ -24,6 +35,7 @@ func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.Linu
return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
}
} else {
+ logrus.Debug("Loading default seccomp profile")
seccompConfig, err = seccomp.GetDefaultProfile(configSpec)
if err != nil {
return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
diff --git a/pkg/spec/createconfig.go b/pkg/spec/createconfig.go
index 244a8d1cd..827caacd6 100644
--- a/pkg/spec/createconfig.go
+++ b/pkg/spec/createconfig.go
@@ -2,6 +2,7 @@ package createconfig
import (
"os"
+ "sort"
"strconv"
"strings"
"syscall"
@@ -106,19 +107,63 @@ type NetworkConfig struct {
PublishAll bool //publish-all
}
+// SeccompPolicy determines which seccomp profile gets applied to the container.
+type SeccompPolicy int
+
+const (
+ // SeccompPolicyDefault - if set use SecurityConfig.SeccompProfilePath,
+ // otherwise use the default profile. The SeccompProfilePath might be
+ // explicitly set by the user.
+ SeccompPolicyDefault SeccompPolicy = iota
+ // SeccompPolicyImage - if set use SecurityConfig.SeccompProfileFromImage,
+ // otherwise follow SeccompPolicyDefault.
+ SeccompPolicyImage
+)
+
+// Map for easy lookups of supported policies.
+var supportedSeccompPolicies = map[string]SeccompPolicy{
+ "": SeccompPolicyDefault,
+ "default": SeccompPolicyDefault,
+ "image": SeccompPolicyImage,
+}
+
+// LookupSeccompPolicy looksup the corresponding SeccompPolicy for the specified
+// string. If none is found, an errors is returned including the list of
+// supported policies.
+// Note that an empty string resolved to SeccompPolicyDefault.
+func LookupSeccompPolicy(s string) (SeccompPolicy, error) {
+ policy, exists := supportedSeccompPolicies[s]
+ if exists {
+ return policy, nil
+ }
+
+ // Sort the keys first as maps are non-deterministic.
+ keys := []string{}
+ for k := range supportedSeccompPolicies {
+ if k != "" {
+ keys = append(keys, k)
+ }
+ }
+ sort.Strings(keys)
+
+ return -1, errors.Errorf("invalid seccomp policy %q: valid policies are %+q", s, keys)
+}
+
// SecurityConfig configures the security features for the container
type SecurityConfig struct {
- CapAdd []string // cap-add
- CapDrop []string // cap-drop
- LabelOpts []string //SecurityOpts
- NoNewPrivs bool //SecurityOpts
- ApparmorProfile string //SecurityOpts
- SeccompProfilePath string //SecurityOpts
- SecurityOpts []string
- Privileged bool //privileged
- ReadOnlyRootfs bool //read-only
- ReadOnlyTmpfs bool //read-only-tmpfs
- Sysctl map[string]string //sysctl
+ CapAdd []string // cap-add
+ CapDrop []string // cap-drop
+ LabelOpts []string //SecurityOpts
+ NoNewPrivs bool //SecurityOpts
+ ApparmorProfile string //SecurityOpts
+ SeccompProfilePath string //SecurityOpts
+ SeccompProfileFromImage string // seccomp profile from the container image
+ SeccompPolicy SeccompPolicy
+ SecurityOpts []string
+ Privileged bool //privileged
+ ReadOnlyRootfs bool //read-only
+ ReadOnlyTmpfs bool //read-only-tmpfs
+ Sysctl map[string]string //sysctl
}
// CreateConfig is a pre OCI spec structure. It represents user input from varlink or the CLI