diff options
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal_linux.go | 22 | ||||
-rw-r--r-- | libpod/options.go | 12 | ||||
-rw-r--r-- | libpod/runtime.go | 3 | ||||
-rw-r--r-- | libpod/runtime_ctr.go | 32 |
4 files changed, 63 insertions, 6 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index f9e161cb3..b77beaf64 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -98,6 +98,28 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } + // Check if the spec file mounts contain the label Relabel flags z or Z. + // If they do, relabel the source directory and then remove the option. + for _, m := range g.Mounts() { + var options []string + for _, o := range m.Options { + switch o { + case "z": + fallthrough + case "Z": + if err := label.Relabel(m.Source, c.MountLabel(), label.IsShared(o)); err != nil { + return nil, errors.Wrapf(err, "relabel failed %q", m.Source) + } + + default: + options = append(options, o) + } + } + m.Options = options + } + + g.SetProcessSelinuxLabel(c.ProcessLabel()) + g.SetLinuxMountLabel(c.MountLabel()) // Remove the default /dev/shm mount to ensure we overwrite it g.RemoveMount("/dev/shm") diff --git a/libpod/options.go b/libpod/options.go index 1a29c0705..977f3f4c2 100644 --- a/libpod/options.go +++ b/libpod/options.go @@ -373,15 +373,17 @@ func WithPrivileged(privileged bool) CtrCreateOption { } } -// WithSELinuxLabels sets the mount label for SELinux. -func WithSELinuxLabels(processLabel, mountLabel string) CtrCreateOption { +// WithSecLabels sets the labels for SELinux. +func WithSecLabels(labelOpts []string) CtrCreateOption { return func(ctr *Container) error { if ctr.valid { return ErrCtrFinalized } - - ctr.config.ProcessLabel = processLabel - ctr.config.MountLabel = mountLabel + var err error + ctr.config.ProcessLabel, ctr.config.MountLabel, err = ctr.runtime.initLabels(labelOpts) + if err != nil { + return errors.Wrapf(err, "failed to init labels") + } return nil } } diff --git a/libpod/runtime.go b/libpod/runtime.go index c69854a17..fbd4c7529 100644 --- a/libpod/runtime.go +++ b/libpod/runtime.go @@ -172,6 +172,8 @@ type RuntimeConfig struct { // However, this can cause significant memory usage if a container has // many ports forwarded to it. Disabling this can save memory. EnablePortReservation bool `toml:"enable_port_reservation"` + // EnableLabeling indicates wether libpod will support container labeling + EnableLabeling bool `toml:"label"` } var ( @@ -209,6 +211,7 @@ var ( InfraCommand: DefaultInfraCommand, InfraImage: DefaultInfraImage, EnablePortReservation: true, + EnableLabeling: true, } ) diff --git a/libpod/runtime_ctr.go b/libpod/runtime_ctr.go index a0b576bcd..6c487e367 100644 --- a/libpod/runtime_ctr.go +++ b/libpod/runtime_ctr.go @@ -11,6 +11,7 @@ import ( "github.com/containers/storage" "github.com/containers/storage/pkg/stringid" spec "github.com/opencontainers/runtime-spec/specs-go" + "github.com/opencontainers/selinux/go-selinux/label" "github.com/pkg/errors" "github.com/sirupsen/logrus" "github.com/ulule/deepcopier" @@ -77,6 +78,7 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.config.Namespace = r.config.Namespace } + ctr.runtime = r for _, option := range options { if err := option(ctr); err != nil { return nil, errors.Wrapf(err, "error running container create option") @@ -85,7 +87,6 @@ func (r *Runtime) newContainer(ctx context.Context, rSpec *spec.Spec, options .. ctr.valid = true ctr.state.State = ContainerStateConfigured - ctr.runtime = r var pod *Pod if ctr.config.Pod != "" { @@ -327,6 +328,10 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool) } } + if r.config.EnableLabeling { + label.ReleaseLabel(c.ProcessLabel()) + r.reserveLabels() + } // Delete the container // Only do this if we're not ContainerStateConfigured - if we are, // we haven't been created in the runtime yet @@ -460,3 +465,28 @@ func (r *Runtime) GetLatestContainer() (*Container, error) { } return ctrs[lastCreatedIndex], nil } + +// reserveLabels walks the list o fcontainers and reserves the label, so new containers will not +// get them. +// TODO Performance wise this should only run if the state has changed since the last time it was run. +func (r *Runtime) reserveLabels() error { + containers, err := r.state.AllContainers() + if err != nil { + return err + } + for _, ctr := range containers { + label.ReserveLabel(ctr.ProcessLabel()) + } + return nil +} + +// initLabels allocates an new label to return to the caller +func (r *Runtime) initLabels(labelOpts []string) (string, string, error) { + if !r.config.EnableLabeling { + return "", "", nil + } + if err := r.reserveLabels(); err != nil { + return "", "", errors.Wrapf(err, "unable to reserve labels") + } + return label.InitLabels(labelOpts) +} |