From c2c148f18d3124c0c84549892a54aa88881a968a Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Wed, 25 Oct 2017 02:35:20 +0000 Subject: [PATCH] We need to release the SELinux label when we destroy the sandbox This will release the MCS Label to be used again. Only do this if we don't have another sandbox using the same label. Also vendor in the latest selinux go bindings, which fixes a leak and properly reserves the SELinux label we are going to use. Signed-off-by: Daniel J Walsh Signed-off-by: Daniel J Walsh --- libkpod/container_server.go | 12 ++++++++++++ vendor.conf | 2 +- .../selinux/go-selinux/label/label_selinux.go | 2 ++ .../opencontainers/selinux/go-selinux/selinux.go | 4 ++-- 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/libkpod/container_server.go b/libkpod/container_server.go index 1bc94871..f4a728e9 100644 --- a/libkpod/container_server.go +++ b/libkpod/container_server.go @@ -19,6 +19,7 @@ import ( "github.com/kubernetes-incubator/cri-o/pkg/storage" "github.com/opencontainers/runc/libcontainer" rspec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/selinux/go-selinux" "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -168,6 +169,7 @@ func New(config *Config) (*ContainerServer, error) { containers: oci.NewMemoryStore(), infraContainers: oci.NewMemoryStore(), sandboxes: make(map[string]*sandbox.Sandbox), + processLevels: make(map[string]int), }, config: config, }, nil @@ -609,6 +611,8 @@ type containerServerState struct { containers oci.ContainerStorer infraContainers oci.ContainerStorer sandboxes map[string]*sandbox.Sandbox + // processLevels The number of sandboxes using the same SELinux MCS level. Need to release MCS Level, when count reaches 0 + processLevels map[string]int } // AddContainer adds a container to the container state store @@ -696,6 +700,7 @@ func (c *ContainerServer) AddSandbox(sb *sandbox.Sandbox) { c.stateLock.Lock() defer c.stateLock.Unlock() c.state.sandboxes[sb.ID()] = sb + c.state.processLevels[selinux.NewContext(sb.ProcessLabel())["level"]]++ } // GetSandbox returns a sandbox by its ID @@ -728,7 +733,14 @@ func (c *ContainerServer) HasSandbox(id string) bool { func (c *ContainerServer) RemoveSandbox(id string) { c.stateLock.Lock() defer c.stateLock.Unlock() + processLabel := c.state.sandboxes[id].ProcessLabel() delete(c.state.sandboxes, id) + level := selinux.NewContext(processLabel)["level"] + c.state.processLevels[level]-- + if c.state.processLevels[level] == 0 { + label.ReleaseLabel(processLabel) + delete(c.state.processLevels, level) + } } // ListSandboxes lists all sandboxes in the state store diff --git a/vendor.conf b/vendor.conf index 93c078e6..f66263ac 100644 --- a/vendor.conf +++ b/vendor.conf @@ -10,7 +10,7 @@ github.com/ostreedev/ostree-go master github.com/containers/storage d7921c6facc516358070a1306689eda18adaa20a github.com/containernetworking/cni v0.4.0 google.golang.org/grpc v1.0.4 https://github.com/grpc/grpc-go -github.com/opencontainers/selinux v1.0.0-rc1 +github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd github.com/opencontainers/go-digest v1.0.0-rc0 github.com/opencontainers/runtime-tools d3f7e9e9e631c7e87552d67dc7c86de33c3fb68a github.com/opencontainers/runc 45bde006ca8c90e089894508708bcf0e2cdf9e13 diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go index 569dcf08..c008a387 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label_selinux.go @@ -49,8 +49,10 @@ func InitLabels(options []string) (string, string, error) { mcon[con[0]] = con[1] } } + _ = ReleaseLabel(processLabel) processLabel = pcon.Get() mountLabel = mcon.Get() + _ = ReserveLabel(processLabel) } return processLabel, mountLabel, nil } diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go index 4cf2c45d..de9316c2 100644 --- a/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go +++ b/vendor/github.com/opencontainers/selinux/go-selinux/selinux.go @@ -213,7 +213,7 @@ func SetFileLabel(path string, label string) error { return lsetxattr(path, xattrNameSelinux, []byte(label), 0) } -// Filecon returns the SELinux label for this path or returns an error. +// FileLabel returns the SELinux label for this path or returns an error. func FileLabel(path string) (string, error) { label, err := lgetxattr(path, xattrNameSelinux) if err != nil { @@ -331,7 +331,7 @@ func EnforceMode() int { } /* -SetEnforce sets the current SELinux mode Enforcing, Permissive. +SetEnforceMode sets the current SELinux mode Enforcing, Permissive. Disabled is not valid, since this needs to be set at boot time. */ func SetEnforceMode(mode int) error {