Allow containers/storage to handle on SELinux labeling

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
This commit is contained in:
Daniel J Walsh
2018-10-18 15:50:11 -04:00
parent 57b0b89d0c
commit a95d71f113
7 changed files with 424 additions and 409 deletions

View File

@ -243,6 +243,8 @@ type ContainerConfig struct {
ProcessLabel string `json:"ProcessLabel,omitempty"`
// SELinux mount label for root filesystem
MountLabel string `json:"MountLabel,omitempty"`
// LabelOpts are options passed in by the user to setup SELinux labels
LabelOpts []string `json:"labelopts,omitempty"`
// User and group to use in the container
// Can be specified by name or UID/GID
User string `json:"user,omitempty"`

File diff suppressed because it is too large Load Diff

View File

@ -79,9 +79,9 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
Name: config.Name,
Driver: driverData.Name,
MountLabel: config.MountLabel,
ProcessLabel: config.ProcessLabel,
EffectiveCaps: spec.Process.Capabilities.Effective,
BoundingCaps: spec.Process.Capabilities.Bounding,
ProcessLabel: spec.Process.SelinuxLabel,
AppArmorProfile: spec.Process.ApparmorProfile,
ExecIDs: execIDs,
GraphDriver: driverData,
@ -93,6 +93,7 @@ func (c *Container) getContainerInspectData(size bool, driverData *inspect.Data)
HairpinMode: false, // TODO
LinkLocalIPv6Address: "", // TODO - do we even support IPv6?
LinkLocalIPv6PrefixLen: 0, // TODO - do we even support IPv6?
Ports: []ocicni.PortMapping{}, // TODO - maybe worth it to put this in Docker format?
SandboxKey: "", // Network namespace path
SecondaryIPAddresses: nil, // TODO - do we support this?

View File

@ -194,12 +194,18 @@ func (c *Container) setupStorage(ctx context.Context) error {
return errors.Wrapf(ErrInvalidArg, "must provide image ID and image name to use an image")
}
var options *storage.ContainerOptions
if c.config.Rootfs == "" {
options = &storage.ContainerOptions{c.config.IDMappings}
options := storage.ContainerOptions{
IDMappingOptions: storage.IDMappingOptions{
HostUIDMapping: true,
HostGIDMapping: true,
},
LabelOpts: c.config.LabelOpts,
}
containerInfo, err := c.runtime.storageService.CreateContainerStorage(ctx, c.runtime.imageContext, c.config.RootfsImageName, c.config.RootfsImageID, c.config.Name, c.config.ID, c.config.MountLabel, options)
if c.config.Rootfs == "" {
options.IDMappingOptions = c.config.IDMappings
}
containerInfo, err := c.runtime.storageService.CreateContainerStorage(ctx, c.runtime.imageContext, c.config.RootfsImageName, c.config.RootfsImageID, c.config.Name, c.config.ID, options)
if err != nil {
return errors.Wrapf(err, "error creating container storage")
}
@ -225,6 +231,8 @@ func (c *Container) setupStorage(ctx context.Context) error {
}
}
c.config.ProcessLabel = containerInfo.ProcessLabel
c.config.MountLabel = containerInfo.MountLabel
c.config.StaticDir = containerInfo.Dir
c.state.RunDir = containerInfo.RunDir
c.state.DestinationRunDir = c.state.RunDir

View File

@ -391,11 +391,7 @@ func WithSecLabels(labelOpts []string) CtrCreateOption {
if ctr.valid {
return ErrCtrFinalized
}
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")
}
ctr.config.LabelOpts = labelOpts
return nil
}
}

View File

@ -11,7 +11,6 @@ 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"
@ -329,10 +328,6 @@ func (r *Runtime) removeContainer(ctx context.Context, c *Container, force bool)
}
}
if r.config.EnableLabeling {
label.ReleaseLabel(c.ProcessLabel())
r.reserveLabels()
}
// Delete the container.
// Not needed in Configured and Exited states, where the container
// doesn't exist in the runtime
@ -467,28 +462,3 @@ 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)
}

View File

@ -27,10 +27,13 @@ func getStorageService(store storage.Store) (*storageService, error) {
// of its nonvolatile and volatile per-container directories, along with a copy
// of the configuration blob from the image that was used to create the
// container, if the image had a configuration.
// It also returns the ProcessLabel and MountLabel selected for the container
type ContainerInfo struct {
Dir string
RunDir string
Config *v1.Image
ProcessLabel string
MountLabel string
}
// RuntimeContainerMetadata is the structure that we encode as JSON and store
@ -59,7 +62,7 @@ func (metadata *RuntimeContainerMetadata) SetMountLabel(mountLabel string) {
// CreateContainerStorage creates the storage end of things. We already have the container spec created
// TO-DO We should be passing in an Image object in the future.
func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID, mountLabel string, options *storage.ContainerOptions) (cinfo ContainerInfo, err error) {
func (r *storageService) CreateContainerStorage(ctx context.Context, systemContext *types.SystemContext, imageName, imageID, containerName, containerID string, options storage.ContainerOptions) (cinfo ContainerInfo, err error) {
var imageConfig *v1.Image
if imageName != "" {
var ref types.ImageReference
@ -101,7 +104,6 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
ImageID: imageID,
ContainerName: containerName,
CreatedAt: time.Now().Unix(),
MountLabel: mountLabel,
}
mdata, err := json.Marshal(&metadata)
if err != nil {
@ -111,15 +113,7 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
// Build the container.
names := []string{containerName}
if options == nil {
options = &storage.ContainerOptions{
IDMappingOptions: storage.IDMappingOptions{
HostUIDMapping: true,
HostGIDMapping: true,
},
}
}
container, err := r.store.CreateContainer(containerID, names, imageID, "", string(mdata), options)
container, err := r.store.CreateContainer(containerID, names, imageID, "", string(mdata), &options)
if err != nil {
logrus.Debugf("failed to create container %s(%s): %v", metadata.ContainerName, containerID, err)
@ -170,6 +164,8 @@ func (r *storageService) CreateContainerStorage(ctx context.Context, systemConte
Dir: containerDir,
RunDir: containerRunDir,
Config: imageConfig,
ProcessLabel: container.ProcessLabel(),
MountLabel: container.MountLabel(),
}, nil
}