Add proper SELinux labeling to buildah run

Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>

Closes: #294
Approved by: nalind
This commit is contained in:
Daniel J Walsh 2017-10-19 21:47:15 +00:00 committed by Atomic Bot
parent cde99f8517
commit 966f32b2ac
10 changed files with 84 additions and 8 deletions

View File

@ -21,6 +21,7 @@ dnf install -y \
libassuan-devel \
libseccomp-devel \
libselinux-devel \
libselinux-utils \
make \
ostree-devel \
which

View File

@ -77,6 +77,10 @@ type Builder struct {
// MountPoint is the last location where the container's root
// filesystem was mounted. It should not be modified.
MountPoint string `json:"mountpoint,omitempty"`
// ProcessLabel is the SELinux process label associated with the container
ProcessLabel string `json:"process-label,omitempty"`
// MountLabel is the SELinux mount label associated with the container
MountLabel string `json:"mount-label,omitempty"`
// ImageAnnotations is a set of key-value pairs which is stored in the
// image's manifest.

View File

@ -1,6 +1,7 @@
package buildah
import (
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
)
@ -13,5 +14,5 @@ func (b *Builder) Delete() error {
b.MountPoint = ""
b.Container = ""
b.ContainerID = ""
return nil
return label.ReleaseLabel(b.ProcessLabel)
}

44
new.go
View File

@ -9,6 +9,8 @@ import (
"github.com/containers/image/transports/alltransports"
"github.com/containers/image/types"
"github.com/containers/storage"
"github.com/opencontainers/selinux/go-selinux"
"github.com/opencontainers/selinux/go-selinux/label"
"github.com/openshift/imagebuilder"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
@ -25,8 +27,35 @@ const (
DefaultTransport = "docker://"
)
func reserveSELinuxLabels(store storage.Store, id string) error {
if selinux.GetEnabled() {
containers, err := store.Containers()
if err != nil {
return err
}
for _, c := range containers {
if id == c.ID {
continue
} else {
b, err := OpenBuilder(store, c.ID)
if err != nil {
if err == storage.ErrContainerUnknown {
continue
}
return err
}
// Prevent containers from using same MCS Label
if err := label.ReserveLabel(b.ProcessLabel); err != nil {
return err
}
}
}
}
return nil
}
func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) {
var err error
var ref types.ImageReference
var img *storage.Image
manifest := []byte{}
@ -45,6 +74,7 @@ func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) {
imageID := ""
if image != "" {
var err error
if options.PullPolicy == PullAlways {
pulledReference, err2 := pullImage(store, options, systemContext)
if err2 != nil {
@ -158,6 +188,14 @@ func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) {
}
}()
if err := reserveSELinuxLabels(store, container.ID); err != nil {
return nil, err
}
processLabel, mountLabel, err := label.InitLabels(nil)
if err != nil {
return nil, err
}
builder := &Builder{
store: store,
Type: containerType,
@ -169,10 +207,12 @@ func newBuilder(store storage.Store, options BuilderOptions) (*Builder, error) {
ContainerID: container.ID,
ImageAnnotations: map[string]string{},
ImageCreatedBy: "",
ProcessLabel: processLabel,
MountLabel: mountLabel,
}
if options.Mount {
_, err = builder.Mount("")
_, err = builder.Mount(mountLabel)
if err != nil {
return nil, errors.Wrapf(err, "error mounting build container")
}

4
run.go
View File

@ -182,7 +182,9 @@ func (b *Builder) Run(command []string, options RunOptions) error {
} else if b.Hostname() != "" {
g.SetHostname(b.Hostname())
}
mountPoint, err := b.Mount("")
g.SetProcessSelinuxLabel(b.ProcessLabel)
g.SetLinuxMountLabel(b.MountLabel)
mountPoint, err := b.Mount(b.MountLabel)
if err != nil {
return err
}

26
tests/selinux.bats Normal file
View File

@ -0,0 +1,26 @@
#!/usr/bin/env bats
load helpers
@test "selinux test" {
if ! which selinuxenabled ; then
skip "No selinuxenabled"
elif ! /usr/sbin/selinuxenabled; then
skip "selinux is disabled"
fi
image=alpine
cid=$(buildah from --pull --signature-policy ${TESTSDIR}/policy.json $image)
firstlabel=$(buildah --debug=false run $cid cat /proc/1/attr/current)
run buildah --debug=false run $cid cat /proc/1/attr/current
[ "$status" -eq 0 ]
[ "$output" == $firstlabel ]
cid1=$(buildah from --pull --signature-policy ${TESTSDIR}/policy.json $image)
run buildah --debug=false run $cid1 cat /proc/1/attr/current
[ "$status" -eq 0 ]
[ "$output" != $firstlabel ]
buildah rm $cid
buildah rm $cid1
}

View File

@ -17,5 +17,5 @@ exec gometalinter.v1 \
--disable=gas \
--disable=aligncheck \
--cyclo-over=40 \
--deadline=240s \
--deadline=480s \
--tests "$@"

View File

@ -27,7 +27,7 @@ github.com/opencontainers/image-spec v1.0.0
github.com/opencontainers/runc master
github.com/opencontainers/runtime-spec v1.0.0
github.com/opencontainers/runtime-tools master
github.com/opencontainers/selinux ba1aefe8057f1d0cfb8e88d0ec1dc85925ef987d
github.com/opencontainers/selinux b29023b86e4a69d1b46b7e7b4e2b6fda03f0b9cd
github.com/openshift/imagebuilder master
github.com/ostreedev/ostree-go aeb02c6b6aa2889db3ef62f7855650755befd460
github.com/pborman/uuid master

View File

@ -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
}

View File

@ -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 {