add pkg/seccomp

Add pkg/seccomp to consolidate all seccomp-policy related code which is
currently scattered across multiple packages and complicating the
creatconfig refactoring.

Signed-off-by: Valentin Rothberg <rothberg@redhat.com>
This commit is contained in:
Valentin Rothberg
2020-02-12 16:59:00 +01:00
parent 62e20b6cd8
commit 65d10ffab3
4 changed files with 65 additions and 55 deletions

View File

@ -22,6 +22,7 @@ import (
"github.com/containers/libpod/pkg/inspect" "github.com/containers/libpod/pkg/inspect"
ns "github.com/containers/libpod/pkg/namespaces" ns "github.com/containers/libpod/pkg/namespaces"
"github.com/containers/libpod/pkg/rootless" "github.com/containers/libpod/pkg/rootless"
"github.com/containers/libpod/pkg/seccomp"
cc "github.com/containers/libpod/pkg/spec" cc "github.com/containers/libpod/pkg/spec"
"github.com/containers/libpod/pkg/util" "github.com/containers/libpod/pkg/util"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
@ -31,10 +32,6 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// seccompLabelKey is the key of the image annotation embedding a seccomp
// profile.
const seccompLabelKey = "io.containers.seccomp.profile"
func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) { func CreateContainer(ctx context.Context, c *GenericCLIResults, runtime *libpod.Runtime) (*libpod.Container, *cc.CreateConfig, error) {
var ( var (
healthCheck *manifest.Schema2HealthConfig healthCheck *manifest.Schema2HealthConfig
@ -713,11 +710,11 @@ func ParseCreateOpts(ctx context.Context, c *GenericCLIResults, runtime *libpod.
// SECCOMP // SECCOMP
if data != nil { if data != nil {
if value, exists := labels[seccompLabelKey]; exists { if value, exists := labels[seccomp.ContainerImageLabel]; exists {
secConfig.SeccompProfileFromImage = value secConfig.SeccompProfileFromImage = value
} }
} }
if policy, err := cc.LookupSeccompPolicy(c.String("seccomp-policy")); err != nil { if policy, err := seccomp.LookupPolicy(c.String("seccomp-policy")); err != nil {
return nil, err return nil, err
} else { } else {
secConfig.SeccompPolicy = policy secConfig.SeccompPolicy = policy

54
pkg/seccomp/seccomp.go Normal file
View File

@ -0,0 +1,54 @@
package seccomp
import (
"sort"
"github.com/pkg/errors"
)
// ContianerImageLabel is the key of the image annotation embedding a seccomp
// profile.
const ContainerImageLabel = "io.containers.seccomp.profile"
// Policy denotes a seccomp policy.
type Policy int
const (
// PolicyDefault - if set use SecurityConfig.SeccompProfilePath,
// otherwise use the default profile. The SeccompProfilePath might be
// explicitly set by the user.
PolicyDefault Policy = iota
// PolicyImage - if set use SecurityConfig.SeccompProfileFromImage,
// otherwise follow SeccompPolicyDefault.
PolicyImage
)
// Map for easy lookups of supported policies.
var supportedPolicies = map[string]Policy{
"": PolicyDefault,
"default": PolicyDefault,
"image": PolicyImage,
}
// LookupPolicy looksup the corresponding Policy 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 LookupPolicy(s string) (Policy, error) {
policy, exists := supportedPolicies[s]
if exists {
return policy, nil
}
// Sort the keys first as maps are non-deterministic.
keys := []string{}
for k := range supportedPolicies {
if k != "" {
keys = append(keys, k)
}
}
sort.Strings(keys)
return -1, errors.Errorf("invalid seccomp policy %q: valid policies are %+q", s, keys)
}

View File

@ -5,9 +5,10 @@ package createconfig
import ( import (
"io/ioutil" "io/ioutil"
"github.com/containers/libpod/pkg/seccomp"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
"github.com/pkg/errors" "github.com/pkg/errors"
seccomp "github.com/seccomp/containers-golang" goSeccomp "github.com/seccomp/containers-golang"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -15,9 +16,9 @@ func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.Linu
var seccompConfig *spec.LinuxSeccomp var seccompConfig *spec.LinuxSeccomp
var err error var err error
if config.SeccompPolicy == SeccompPolicyImage && config.SeccompProfileFromImage != "" { if config.SeccompPolicy == seccomp.PolicyImage && config.SeccompProfileFromImage != "" {
logrus.Debug("Loading seccomp profile from the security config") logrus.Debug("Loading seccomp profile from the security config")
seccompConfig, err = seccomp.LoadProfile(config.SeccompProfileFromImage, configSpec) seccompConfig, err = goSeccomp.LoadProfile(config.SeccompProfileFromImage, configSpec)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "loading seccomp profile failed") return nil, errors.Wrap(err, "loading seccomp profile failed")
} }
@ -30,13 +31,13 @@ func getSeccompConfig(config *SecurityConfig, configSpec *spec.Spec) (*spec.Linu
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath) return nil, errors.Wrapf(err, "opening seccomp profile (%s) failed", config.SeccompProfilePath)
} }
seccompConfig, err = seccomp.LoadProfile(string(seccompProfile), configSpec) seccompConfig, err = goSeccomp.LoadProfile(string(seccompProfile), configSpec)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
} }
} else { } else {
logrus.Debug("Loading default seccomp profile") logrus.Debug("Loading default seccomp profile")
seccompConfig, err = seccomp.GetDefaultProfile(configSpec) seccompConfig, err = goSeccomp.GetDefaultProfile(configSpec)
if err != nil { if err != nil {
return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath) return nil, errors.Wrapf(err, "loading seccomp profile (%s) failed", config.SeccompProfilePath)
} }

View File

@ -2,7 +2,6 @@ package createconfig
import ( import (
"os" "os"
"sort"
"strconv" "strconv"
"strings" "strings"
"syscall" "syscall"
@ -11,6 +10,7 @@ import (
"github.com/containers/libpod/libpod" "github.com/containers/libpod/libpod"
"github.com/containers/libpod/libpod/define" "github.com/containers/libpod/libpod/define"
"github.com/containers/libpod/pkg/namespaces" "github.com/containers/libpod/pkg/namespaces"
"github.com/containers/libpod/pkg/seccomp"
"github.com/containers/storage" "github.com/containers/storage"
"github.com/docker/go-connections/nat" "github.com/docker/go-connections/nat"
spec "github.com/opencontainers/runtime-spec/specs-go" spec "github.com/opencontainers/runtime-spec/specs-go"
@ -107,48 +107,6 @@ type NetworkConfig struct {
PublishAll bool //publish-all 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 // SecurityConfig configures the security features for the container
type SecurityConfig struct { type SecurityConfig struct {
CapAdd []string // cap-add CapAdd []string // cap-add
@ -158,7 +116,7 @@ type SecurityConfig struct {
ApparmorProfile string //SecurityOpts ApparmorProfile string //SecurityOpts
SeccompProfilePath string //SecurityOpts SeccompProfilePath string //SecurityOpts
SeccompProfileFromImage string // seccomp profile from the container image SeccompProfileFromImage string // seccomp profile from the container image
SeccompPolicy SeccompPolicy SeccompPolicy seccomp.Policy
SecurityOpts []string SecurityOpts []string
Privileged bool //privileged Privileged bool //privileged
ReadOnlyRootfs bool //read-only ReadOnlyRootfs bool //read-only