diff --git a/libkpod/container_server.go b/libkpod/container_server.go index 4c6c2d98..53c51c7d 100644 --- a/libkpod/container_server.go +++ b/libkpod/container_server.go @@ -5,6 +5,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "sync" "time" @@ -168,6 +169,7 @@ func New(config *Config) (*ContainerServer, error) { containers: oci.NewMemoryStore(), infraContainers: oci.NewMemoryStore(), sandboxes: make(map[string]*sandbox.Sandbox), + selinuxLevels: make(map[string]int), }, config: config, }, nil @@ -611,6 +613,8 @@ type containerServerState struct { containers oci.ContainerStorer infraContainers oci.ContainerStorer sandboxes map[string]*sandbox.Sandbox + // process labels level reference counter to release them when not used anymore + selinuxLevels map[string]int } // AddContainer adds a container to the container state store @@ -693,11 +697,21 @@ func (c *ContainerServer) ListContainers(filters ...func(*oci.Container) bool) ( return filteredContainers, nil } +// TODO: move this to opencontainers/selinux +func getSELinuxLevel(label string) string { + if len(label) != 0 { + con := strings.SplitN(label, ":", 4) + return con[3] + } + return "" +} + // AddSandbox adds a sandbox to the sandbox state store func (c *ContainerServer) AddSandbox(sb *sandbox.Sandbox) { c.stateLock.Lock() defer c.stateLock.Unlock() c.state.sandboxes[sb.ID()] = sb + c.state.selinuxLevels[getSELinuxLevel(sb.ProcessLabel())]++ } // GetSandbox returns a sandbox by its ID @@ -731,6 +745,14 @@ func (c *ContainerServer) RemoveSandbox(id string) { c.stateLock.Lock() defer c.stateLock.Unlock() delete(c.state.sandboxes, id) + processLabel := c.state.sandboxes[id].ProcessLabel() + level := getSELinuxLevel(processLabel) + c.state.selinuxLevels[level]-- + labelCounter := c.state.selinuxLevels[level] + if labelCounter == 0 { + label.ReleaseLabel(processLabel) + delete(c.state.selinuxLevels, processLabel) + } } // 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 {