diff --git a/internal/config/seccomp/seccomp.go b/internal/config/seccomp/seccomp.go index 7b268e5a389..a7434ce67d0 100644 --- a/internal/config/seccomp/seccomp.go +++ b/internal/config/seccomp/seccomp.go @@ -1,12 +1,19 @@ package seccomp import ( + "context" "io/ioutil" + "path/filepath" + "strings" "github.com/containers/common/pkg/seccomp" + "github.com/cri-o/cri-o/internal/log" + "github.com/cri-o/cri-o/server/cri/types" json "github.com/json-iterator/go" + "github.com/opencontainers/runtime-tools/generate" "github.com/pkg/errors" "github.com/sirupsen/logrus" + k8sV1 "k8s.io/api/core/v1" ) // Config is the global seccomp configuration type @@ -84,3 +91,148 @@ func (c *Config) IsDisabled() bool { func (c *Config) Profile() *seccomp.Seccomp { return c.profile } + +// Setup can be used to setup the seccomp profile. +func (c *Config) Setup( + ctx context.Context, + specGenerator *generate.Generator, + profileField *types.SecurityProfile, + profilePath string, +) error { + if profileField == nil { + // Path based seccomp profiles will be used with a higher priority and are + // going to be removed in future Kubernetes versions. + if err := c.setupFromPath(ctx, specGenerator, profilePath); err != nil { + return errors.Wrap(err, "from profile path") + } + } else if err := c.setupFromField(ctx, specGenerator, profileField); err != nil { + // Field based seccomp profiles are newer than the path based ones and will + // be the standard in future Kubernetes versions. + return errors.Wrap(err, "from field") + } + + return nil +} + +func (c *Config) setupFromPath( + ctx context.Context, specGenerator *generate.Generator, profilePath string, +) error { + log.Debugf(ctx, "Setup seccomp from profile path: %s", profilePath) + + if profilePath == "" { + if !c.UseDefaultWhenEmpty() { + // running w/o seccomp, aka unconfined + specGenerator.Config.Linux.Seccomp = nil + return nil + } + // default to SeccompProfileRuntimeDefault if user sets UseDefaultWhenEmpty + profilePath = k8sV1.SeccompProfileRuntimeDefault + } + + // kubelet defaults sandboxes to run as `runtime/default`, we consider the + // default profilePath as unconfined if Seccomp disabled + // https://github.com/kubernetes/kubernetes/blob/12d9183da03d86c65f9f17e3e28be3c7c18ed22a/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go#L162-L163 + if c.IsDisabled() { + if profilePath == k8sV1.SeccompProfileRuntimeDefault { + // running w/o seccomp, aka unconfined + specGenerator.Config.Linux.Seccomp = nil + return nil + } + if profilePath != k8sV1.SeccompProfileNameUnconfined { + return errors.New( + "seccomp is not enabled, cannot run with a profile", + ) + } + + log.Warnf(ctx, "Seccomp is not enabled in the kernel, running container without profile") + } + + if profilePath == k8sV1.SeccompProfileNameUnconfined { + // running w/o seccomp, aka unconfined + specGenerator.Config.Linux.Seccomp = nil + return nil + } + + // Load the default seccomp profile from the server if the profilePath is a + // default one + if profilePath == k8sV1.SeccompProfileRuntimeDefault || profilePath == k8sV1.DeprecatedSeccompProfileDockerDefault { + linuxSpecs, err := seccomp.LoadProfileFromConfig( + c.Profile(), specGenerator.Config, + ) + if err != nil { + return errors.Wrap(err, "load default profile") + } + + specGenerator.Config.Linux.Seccomp = linuxSpecs + return nil + } + + // Load local seccomp profiles including their availability validation + if !strings.HasPrefix(profilePath, k8sV1.SeccompLocalhostProfileNamePrefix) { + return errors.Errorf("unknown seccomp profile path: %q", profilePath) + } + + fname := strings.TrimPrefix(profilePath, k8sV1.SeccompLocalhostProfileNamePrefix) + file, err := ioutil.ReadFile(filepath.FromSlash(fname)) + if err != nil { + return errors.Errorf("cannot load seccomp profile %q: %v", fname, err) + } + + linuxSpecs, err := seccomp.LoadProfileFromBytes(file, specGenerator.Config) + if err != nil { + return err + } + specGenerator.Config.Linux.Seccomp = linuxSpecs + return nil +} + +func (c *Config) setupFromField( + ctx context.Context, + specGenerator *generate.Generator, + profileField *types.SecurityProfile, +) error { + log.Debugf(ctx, "Setup seccomp from profile field: %+v", profileField) + + if c.IsDisabled() { + if profileField.ProfileType != types.SecurityProfileTypeUnconfined { + return errors.Errorf( + "seccomp is not enabled, cannot run with a profile", + ) + } + log.Warnf(ctx, "seccomp is not enabled, running without profile") + specGenerator.Config.Linux.Seccomp = nil + return nil + } + + if profileField.ProfileType == types.SecurityProfileTypeUnconfined { + // running w/o seccomp, aka unconfined + specGenerator.Config.Linux.Seccomp = nil + return nil + } + + if profileField.ProfileType == types.SecurityProfileTypeRuntimeDefault { + linuxSpecs, err := seccomp.LoadProfileFromConfig( + c.Profile(), specGenerator.Config, + ) + if err != nil { + return errors.Wrap(err, "load default profile") + } + specGenerator.Config.Linux.Seccomp = linuxSpecs + return nil + } + + // Load local seccomp profiles including their availability validation + file, err := ioutil.ReadFile(filepath.FromSlash(profileField.LocalhostRef)) + if err != nil { + return errors.Wrapf( + err, "unable to load local profile %q", profileField.LocalhostRef, + ) + } + + linuxSpecs, err := seccomp.LoadProfileFromBytes(file, specGenerator.Config) + if err != nil { + return errors.Wrap(err, "load local profile") + } + specGenerator.Config.Linux.Seccomp = linuxSpecs + return nil +} diff --git a/internal/config/seccomp/seccomp_test.go b/internal/config/seccomp/seccomp_test.go index c804d61120e..8677e71d191 100644 --- a/internal/config/seccomp/seccomp_test.go +++ b/internal/config/seccomp/seccomp_test.go @@ -1,12 +1,16 @@ package seccomp_test import ( + "context" "io/ioutil" containers_seccomp "github.com/containers/common/pkg/seccomp" "github.com/cri-o/cri-o/internal/config/seccomp" + "github.com/cri-o/cri-o/server/cri/types" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" + "github.com/opencontainers/runtime-tools/generate" + k8sV1 "k8s.io/api/core/v1" ) // The actual test suite @@ -18,6 +22,30 @@ var _ = t.Describe("Config", func() { Expect(sut).NotTo(BeNil()) }) + writeProfileFile := func() string { + file := t.MustTempFile("") + Expect(ioutil.WriteFile(file, []byte(`{ + "names": ["clone"], + "action": "SCMP_ACT_ALLOW", + "args": [ + { + "index": 1, + "value": 2080505856, + "valueTwo": 0, + "op": "SCMP_CMP_MASKED_EQ" + } + ], + "comment": "s390 parameter ordering for clone is different", + "includes": { + "arches": ["s390", "s390x"] + }, + "excludes": { + "caps": ["CAP_SYS_ADMIN"] + } + }`), 0o644)).To(BeNil()) + return file + } + t.Describe("Profile", func() { It("should be the default without any load", func() { // Given @@ -42,26 +70,7 @@ var _ = t.Describe("Config", func() { It("should succeed with profile", func() { // Given - file := t.MustTempFile("") - Expect(ioutil.WriteFile(file, []byte(`{ - "names": ["clone"], - "action": "SCMP_ACT_ALLOW", - "args": [ - { - "index": 1, - "value": 2080505856, - "valueTwo": 0, - "op": "SCMP_CMP_MASKED_EQ" - } - ], - "comment": "s390 parameter ordering for clone is different", - "includes": { - "arches": ["s390", "s390x"] - }, - "excludes": { - "caps": ["CAP_SYS_ADMIN"] - } - }`), 0o644)).To(BeNil()) + file := writeProfileFile() // When err := sut.LoadProfile(file) @@ -81,4 +90,121 @@ var _ = t.Describe("Config", func() { }) } }) + + t.Describe("Setup", func() { + It("should succeed with profile from file", func() { + // Given + generator, err := generate.New("linux") + Expect(err).To(BeNil()) + file := writeProfileFile() + + // When + err = sut.Setup( + context.Background(), + &generator, + nil, + k8sV1.SeccompLocalhostProfileNamePrefix+file, + ) + + // Then + Expect(err).To(BeNil()) + }) + + It("should succeed with profile from file and runtime default", func() { + // Given + generator, err := generate.New("linux") + Expect(err).To(BeNil()) + + // When + err = sut.Setup( + context.Background(), + &generator, + nil, + k8sV1.SeccompProfileRuntimeDefault, + ) + + // Then + Expect(err).To(BeNil()) + }) + + It("should fail with profile from file if wrong filename", func() { + // Given + generator, err := generate.New("linux") + Expect(err).To(BeNil()) + + // When + err = sut.Setup( + context.Background(), + &generator, + nil, + "not-existing", + ) + + // Then + Expect(err).NotTo(BeNil()) + }) + + It("should succeed with custom profile from field", func() { + // Given + generator, err := generate.New("linux") + Expect(err).To(BeNil()) + field := &types.SecurityProfile{ + ProfileType: types.SecurityProfileTypeRuntimeDefault, + } + + // When + err = sut.Setup( + context.Background(), + &generator, + field, + "", + ) + + // Then + Expect(err).To(BeNil()) + }) + + It("should succeed with custom profile from field", func() { + // Given + generator, err := generate.New("linux") + Expect(err).To(BeNil()) + file := writeProfileFile() + field := &types.SecurityProfile{ + ProfileType: types.SecurityProfileTypeLocalhost, + LocalhostRef: file, + } + + // When + err = sut.Setup( + context.Background(), + &generator, + field, + "", + ) + + // Then + Expect(err).To(BeNil()) + }) + + It("should fail with custom profile from field if not existing", func() { + // Given + generator, err := generate.New("linux") + Expect(err).To(BeNil()) + field := &types.SecurityProfile{ + ProfileType: types.SecurityProfileTypeLocalhost, + LocalhostRef: "not-existing", + } + + // When + err = sut.Setup( + context.Background(), + &generator, + field, + "", + ) + + // Then + Expect(err).NotTo(BeNil()) + }) + }) }) diff --git a/server/container_create.go b/server/container_create.go index 94f26efe4cc..8bfbe1e4e01 100644 --- a/server/container_create.go +++ b/server/container_create.go @@ -3,13 +3,11 @@ package server import ( "context" "fmt" - "io/ioutil" "os" "path/filepath" "strconv" "strings" - "github.com/containers/common/pkg/seccomp" "github.com/containers/storage/pkg/idtools" "github.com/containers/storage/pkg/mount" "github.com/containers/storage/pkg/stringid" @@ -25,7 +23,6 @@ import ( rspec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" "github.com/pkg/errors" - k8sV1 "k8s.io/api/core/v1" ) type orderedMounts []rspec.Mount @@ -573,59 +570,3 @@ func isInCRIMounts(dst string, mounts []*types.Mount) bool { } return false } - -func (s *Server) setupSeccomp(ctx context.Context, specgen *generate.Generator, profile string) error { - if profile == "" { - if !s.Config().Seccomp().UseDefaultWhenEmpty() { - // running w/o seccomp, aka unconfined - specgen.Config.Linux.Seccomp = nil - return nil - } - // default to SeccompProfileRuntimeDefault if user sets UseDefaultWhenEmpty - profile = k8sV1.SeccompProfileRuntimeDefault - } - // kubelet defaults sandboxes to run as `runtime/default`, we consider the default profile as unconfined if Seccomp disabled - // https://github.com/kubernetes/kubernetes/blob/12d9183da03d86c65f9f17e3e28be3c7c18ed22a/pkg/kubelet/kuberuntime/kuberuntime_sandbox.go#L162-L163 - if s.Config().Seccomp().IsDisabled() { - if profile == k8sV1.SeccompProfileRuntimeDefault { - // running w/o seccomp, aka unconfined - specgen.Config.Linux.Seccomp = nil - return nil - } - if profile != k8sV1.SeccompProfileNameUnconfined { - return fmt.Errorf("seccomp is not enabled in your kernel, cannot run with a profile") - } - log.Warnf(ctx, "seccomp is not enabled in your kernel, running container without profile") - } - if profile == k8sV1.SeccompProfileNameUnconfined { - // running w/o seccomp, aka unconfined - specgen.Config.Linux.Seccomp = nil - return nil - } - - // Load the default seccomp profile from the server if the profile is a default one - if profile == k8sV1.SeccompProfileRuntimeDefault || profile == k8sV1.DeprecatedSeccompProfileDockerDefault { - linuxSpecs, err := seccomp.LoadProfileFromConfig(s.Config().Seccomp().Profile(), specgen.Config) - if err != nil { - return err - } - specgen.Config.Linux.Seccomp = linuxSpecs - return nil - } - - // Load local seccomp profiles including their availability validation - if !strings.HasPrefix(profile, k8sV1.SeccompLocalhostProfileNamePrefix) { - return fmt.Errorf("unknown seccomp profile option: %q", profile) - } - fname := strings.TrimPrefix(profile, k8sV1.SeccompLocalhostProfileNamePrefix) - file, err := ioutil.ReadFile(filepath.FromSlash(fname)) - if err != nil { - return fmt.Errorf("cannot load seccomp profile %q: %v", fname, err) - } - linuxSpecs, err := seccomp.LoadProfileFromBytes(file, specgen.Config) - if err != nil { - return err - } - specgen.Config.Linux.Seccomp = linuxSpecs - return nil -} diff --git a/server/container_create_linux.go b/server/container_create_linux.go index c895237d85e..988a92790d2 100644 --- a/server/container_create_linux.go +++ b/server/container_create_linux.go @@ -561,10 +561,14 @@ func (s *Server) createSandboxContainer(ctx context.Context, ctr ctrIface.Contai specgen.AddProcessEnv("HOSTNAME", sb.Hostname()) created := time.Now() - spp := containerConfig.Linux.SecurityContext.SeccompProfilePath if !ctr.Privileged() { - if err := s.setupSeccomp(ctx, specgen, spp); err != nil { - return nil, err + if err := s.Config().Seccomp().Setup( + ctx, + specgen, + securityContext.Seccomp, + containerConfig.Linux.SecurityContext.SeccompProfilePath, + ); err != nil { + return nil, errors.Wrap(err, "setup seccomp") } } @@ -723,7 +727,7 @@ func (s *Server) createSandboxContainer(ctx context.Context, ctr ctrIface.Contai ociContainer.SetSpec(specgen.Config) ociContainer.SetMountPoint(mountPoint) - ociContainer.SetSeccompProfilePath(spp) + ociContainer.SetSeccompProfilePath(containerConfig.Linux.SecurityContext.SeccompProfilePath) for _, cv := range containerVolumes { ociContainer.AddVolume(cv) diff --git a/server/cri/types/types.go b/server/cri/types/types.go index b0a0278734f..01e8939860a 100644 --- a/server/cri/types/types.go +++ b/server/cri/types/types.go @@ -324,6 +324,8 @@ type LinuxSandboxSecurityContext struct { SelinuxOptions *SELinuxOption RunAsUser *Int64Value RunAsGroup *Int64Value + Seccomp *SecurityProfile + Apparmor *SecurityProfile SeccompProfilePath string SupplementalGroups []int64 ReadonlyRootfs bool @@ -511,6 +513,8 @@ type LinuxContainerSecurityContext struct { SelinuxOptions *SELinuxOption RunAsUser *Int64Value RunAsGroup *Int64Value + Seccomp *SecurityProfile + Apparmor *SecurityProfile RunAsUsername string ApparmorProfile string SeccompProfilePath string @@ -620,3 +624,16 @@ type ContainerStatsFilter struct { PodSandboxID string LabelSelector map[string]string } + +type SecurityProfile struct { + ProfileType SecurityProfileType + LocalhostRef string +} + +type SecurityProfileType int32 + +const ( + SecurityProfileTypeRuntimeDefault SecurityProfileType = 0 + SecurityProfileTypeUnconfined SecurityProfileType = 1 + SecurityProfileTypeLocalhost SecurityProfileType = 2 +) diff --git a/server/cri/v1/rpc_create_container.go b/server/cri/v1/rpc_create_container.go index c260fcefbab..b86783976fb 100644 --- a/server/cri/v1/rpc_create_container.go +++ b/server/cri/v1/rpc_create_container.go @@ -82,6 +82,18 @@ func (s *service) CreateContainer( DropCapabilities: req.Config.Linux.SecurityContext.Capabilities.DropCapabilities, } } + if req.Config.Linux.SecurityContext.Seccomp != nil { + r.Config.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.Config.Linux.SecurityContext.Apparmor != nil { + r.Config.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.Config.Linux.SecurityContext.NamespaceOptions != nil { r.Config.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.Config.Linux.SecurityContext.NamespaceOptions.Network), @@ -189,6 +201,18 @@ func (s *service) CreateContainer( NamespaceOptions: &types.NamespaceOption{}, SelinuxOptions: &types.SELinuxOption{}, } + if req.SandboxConfig.Linux.SecurityContext.Seccomp != nil { + r.SandboxConfig.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.SandboxConfig.Linux.SecurityContext.Apparmor != nil { + r.SandboxConfig.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.SandboxConfig.Linux.SecurityContext.NamespaceOptions != nil { r.SandboxConfig.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.SandboxConfig.Linux.SecurityContext.NamespaceOptions.Network), diff --git a/server/cri/v1/rpc_pull_image.go b/server/cri/v1/rpc_pull_image.go index 1e85878cdfe..897d8ea9687 100644 --- a/server/cri/v1/rpc_pull_image.go +++ b/server/cri/v1/rpc_pull_image.go @@ -87,6 +87,18 @@ func (s *service) PullImage( NamespaceOptions: &types.NamespaceOption{}, SelinuxOptions: &types.SELinuxOption{}, } + if req.SandboxConfig.Linux.SecurityContext.Seccomp != nil { + r.SandboxConfig.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.SandboxConfig.Linux.SecurityContext.Apparmor != nil { + r.SandboxConfig.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.SandboxConfig.Linux.SecurityContext.NamespaceOptions != nil { r.SandboxConfig.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.SandboxConfig.Linux.SecurityContext.NamespaceOptions.Network), diff --git a/server/cri/v1/rpc_run_pod_sandbox.go b/server/cri/v1/rpc_run_pod_sandbox.go index ba1e46429c8..76c6fa6c566 100644 --- a/server/cri/v1/rpc_run_pod_sandbox.go +++ b/server/cri/v1/rpc_run_pod_sandbox.go @@ -62,6 +62,18 @@ func (s *service) RunPodSandbox( NamespaceOptions: &types.NamespaceOption{}, SelinuxOptions: &types.SELinuxOption{}, } + if req.Config.Linux.SecurityContext.Seccomp != nil { + r.Config.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.Config.Linux.SecurityContext.Apparmor != nil { + r.Config.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.Config.Linux.SecurityContext.NamespaceOptions != nil { r.Config.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.Config.Linux.SecurityContext.NamespaceOptions.Network), diff --git a/server/cri/v1alpha2/rpc_create_container.go b/server/cri/v1alpha2/rpc_create_container.go index 329c6789b40..ef2b7d7e4d0 100644 --- a/server/cri/v1alpha2/rpc_create_container.go +++ b/server/cri/v1alpha2/rpc_create_container.go @@ -82,6 +82,18 @@ func (s *service) CreateContainer( DropCapabilities: req.Config.Linux.SecurityContext.Capabilities.DropCapabilities, } } + if req.Config.Linux.SecurityContext.Seccomp != nil { + r.Config.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.Config.Linux.SecurityContext.Apparmor != nil { + r.Config.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.Config.Linux.SecurityContext.NamespaceOptions != nil { r.Config.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.Config.Linux.SecurityContext.NamespaceOptions.Network), @@ -189,6 +201,18 @@ func (s *service) CreateContainer( NamespaceOptions: &types.NamespaceOption{}, SelinuxOptions: &types.SELinuxOption{}, } + if req.SandboxConfig.Linux.SecurityContext.Seccomp != nil { + r.SandboxConfig.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.SandboxConfig.Linux.SecurityContext.Apparmor != nil { + r.SandboxConfig.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.SandboxConfig.Linux.SecurityContext.NamespaceOptions != nil { r.SandboxConfig.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.SandboxConfig.Linux.SecurityContext.NamespaceOptions.Network), diff --git a/server/cri/v1alpha2/rpc_pull_image.go b/server/cri/v1alpha2/rpc_pull_image.go index 3e2fa17b486..43d5c0e4401 100644 --- a/server/cri/v1alpha2/rpc_pull_image.go +++ b/server/cri/v1alpha2/rpc_pull_image.go @@ -87,6 +87,18 @@ func (s *service) PullImage( NamespaceOptions: &types.NamespaceOption{}, SelinuxOptions: &types.SELinuxOption{}, } + if req.SandboxConfig.Linux.SecurityContext.Seccomp != nil { + r.SandboxConfig.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.SandboxConfig.Linux.SecurityContext.Apparmor != nil { + r.SandboxConfig.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.SandboxConfig.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.SandboxConfig.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.SandboxConfig.Linux.SecurityContext.NamespaceOptions != nil { r.SandboxConfig.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.SandboxConfig.Linux.SecurityContext.NamespaceOptions.Network), diff --git a/server/cri/v1alpha2/rpc_run_pod_sandbox.go b/server/cri/v1alpha2/rpc_run_pod_sandbox.go index a93bd918d54..3634ee1cd54 100644 --- a/server/cri/v1alpha2/rpc_run_pod_sandbox.go +++ b/server/cri/v1alpha2/rpc_run_pod_sandbox.go @@ -62,6 +62,18 @@ func (s *service) RunPodSandbox( NamespaceOptions: &types.NamespaceOption{}, SelinuxOptions: &types.SELinuxOption{}, } + if req.Config.Linux.SecurityContext.Seccomp != nil { + r.Config.Linux.SecurityContext.Seccomp = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Seccomp.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Seccomp.LocalhostRef, + } + } + if req.Config.Linux.SecurityContext.Apparmor != nil { + r.Config.Linux.SecurityContext.Apparmor = &types.SecurityProfile{ + ProfileType: types.SecurityProfileType(req.Config.Linux.SecurityContext.Apparmor.ProfileType), + LocalhostRef: req.Config.Linux.SecurityContext.Apparmor.LocalhostRef, + } + } if req.Config.Linux.SecurityContext.NamespaceOptions != nil { r.Config.Linux.SecurityContext.NamespaceOptions = &types.NamespaceOption{ Network: types.NamespaceMode(req.Config.Linux.SecurityContext.NamespaceOptions.Network), diff --git a/server/sandbox_run_linux.go b/server/sandbox_run_linux.go index 274a6ca2123..2c663f399f5 100644 --- a/server/sandbox_run_linux.go +++ b/server/sandbox_run_linux.go @@ -830,12 +830,14 @@ func (s *Server) runPodSandbox(ctx context.Context, req *types.RunPodSandboxRequ }, ) - spp := securityContext.SeccompProfilePath - g.AddAnnotation(annotations.SeccompProfilePath, spp) - sb.SetSeccompProfilePath(spp) + seccompProfilePath := securityContext.SeccompProfilePath + g.AddAnnotation(annotations.SeccompProfilePath, seccompProfilePath) + sb.SetSeccompProfilePath(seccompProfilePath) if !privileged { - if err := s.setupSeccomp(ctx, g, spp); err != nil { - return nil, err + if err := s.Config().Seccomp().Setup( + ctx, g, securityContext.Seccomp, seccompProfilePath, + ); err != nil { + return nil, errors.Wrap(err, "setup seccomp") } } diff --git a/test/ctr_seccomp.bats b/test/ctr_seccomp.bats index a5ce46362a4..6fca12fa991 100644 --- a/test/ctr_seccomp.bats +++ b/test/ctr_seccomp.bats @@ -61,7 +61,7 @@ function teardown() { pod_id=$(crictl runp "$TESTDATA"/sandbox_config.json) run crictl create "$pod_id" "$TESTDIR"/seccomp.json "$TESTDATA"/sandbox_config.json [[ "$status" -ne 0 ]] - [[ "$output" =~ "unknown seccomp profile option:" ]] + [[ "$output" =~ "unknown seccomp profile " ]] [[ "$output" =~ "wontwork" ]] }