From d2ea9cc2fa3d381b00a8b445619fc9967fe93ef9 Mon Sep 17 00:00:00 2001 From: Daniel J Walsh Date: Sun, 22 Oct 2017 10:26:14 +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 557701e9..5ac9f585 100644 --- a/vendor.conf +++ b/vendor.conf @@ -10,7 +10,7 @@ github.com/ostreedev/ostree-go master github.com/containers/storage 64bf27465d0d1edd89e7a4ce49866fea01145782 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 {