Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

protect snapshot layers via SELinux policy #935

Merged
merged 10 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
From c134a9befa59fd5ab670a9c250f74cb3e4c88844 Mon Sep 17 00:00:00 2001
From: Darren Shepherd <darren@rancher.com>
Date: Mon, 24 Feb 2020 09:53:42 -0700
Subject: [PATCH] Use spec's mountLabel when mounting the rootfs

In NewContainer if a SnapshotKey is used and the spec has
a mountLabel specified, that mountLabel should be used to mount
the rootfs.

Signed-off-by: Darren Shepherd <darren@rancher.com>
---
container.go | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/container.go b/container.go
index fd880d0e..187934ea 100644
--- a/container.go
+++ b/container.go
@@ -36,6 +36,7 @@ import (
prototypes "github.com/gogo/protobuf/types"
ver "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
)

@@ -242,7 +243,17 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N
if err != nil {
return nil, err
}
+ spec, err := c.Spec(ctx)
+ if err != nil {
+ return nil, err
+ }
for _, m := range mounts {
+ if spec.Linux != nil && spec.Linux.MountLabel != "" {
+ context := label.FormatMountLabel("", spec.Linux.MountLabel)
+ if context != "" {
+ m.Options = append(m.Options, context)
+ }
+ }
request.Rootfs = append(request.Rootfs, &types.Mount{
Type: m.Type,
Source: m.Source,
--
2.21.0

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
From dd750a2271b64758c5c2240b6ed9586dd79ccb7a Mon Sep 17 00:00:00 2001
From 620046d6f883433ef1d030ea9c428acbd1e71035 Mon Sep 17 00:00:00 2001
From: Matt Briggs <brigmatt@amazon.com>
Date: Wed, 1 Apr 2020 16:55:04 -0700
Subject: [PATCH] reduce logging when no errors have occurred
Subject: [PATCH] cri: reduce logging when no errors have occurred

---
.../containerd/cri/pkg/server/container_execsync.go | 3 ++-
Expand All @@ -10,7 +10,7 @@ Subject: [PATCH] reduce logging when no errors have occurred
3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/vendor/github.com/containerd/cri/pkg/server/container_execsync.go b/vendor/github.com/containerd/cri/pkg/server/container_execsync.go
index b46e6e56..36e64c03 100644
index b46e6e5..36e64c0 100644
--- a/vendor/github.com/containerd/cri/pkg/server/container_execsync.go
+++ b/vendor/github.com/containerd/cri/pkg/server/container_execsync.go
@@ -186,10 +186,11 @@ func (c *criService) execInContainer(ctx context.Context, id string, opts execOp
Expand All @@ -27,7 +27,7 @@ index b46e6e56..36e64c03 100644
log.G(ctx).Debugf("Stream pipe for exec process %q done", execID)
return &code, nil
diff --git a/vendor/github.com/containerd/cri/pkg/server/instrumented_service.go b/vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
index 8a23c139..11e1f340 100644
index 8a23c13..11e1f34 100644
--- a/vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
+++ b/vendor/github.com/containerd/cri/pkg/server/instrumented_service.go
@@ -247,12 +247,12 @@ func (in *instrumentedService) ExecSync(ctx context.Context, r *runtime.ExecSync
Expand All @@ -46,7 +46,7 @@ index 8a23c139..11e1f340 100644
res.GetStdout(), res.GetStderr())
}
diff --git a/vendor/github.com/containerd/cri/pkg/server/io/exec_io.go b/vendor/github.com/containerd/cri/pkg/server/io/exec_io.go
index 3b2c36a9..4e868b63 100644
index 3b2c36a..4e868b6 100644
--- a/vendor/github.com/containerd/cri/pkg/server/io/exec_io.go
+++ b/vendor/github.com/containerd/cri/pkg/server/io/exec_io.go
@@ -99,7 +99,7 @@ func (e *ExecIO) Attach(opts AttachOptions) <-chan struct{} {
Expand All @@ -59,5 +59,5 @@ index 3b2c36a9..4e868b63 100644

if opts.Stdout != nil {
--
2.21.1 (Apple Git-122.3)
2.21.0

98 changes: 98 additions & 0 deletions packages/containerd/2001-selinux-add-DefaultLabels-helper.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
From b9b8e01729ea72e081c0488f21a6b7eff9836de9 Mon Sep 17 00:00:00 2001
From: Ben Cressey <bcressey@amazon.com>
Date: Wed, 29 Apr 2020 15:10:04 +0000
Subject: [PATCH 2001/2002] selinux: add DefaultLabels helper
bcressey marked this conversation as resolved.
Show resolved Hide resolved

This is very similar to the existing InitLabels helper function, but
avoids allocating a new MCS label pair which would isolate containers
in a pod from each other and break compatibility.

In v1.4.0, containerd will have support for ensuring that containers
in a pod end up sharing the MCS label pair, which should address the
compatibility problem.

Signed-off-by: Ben Cressey <bcressey@amazon.com>
---
.../selinux/go-selinux/label/label.go | 6 +++
.../selinux/go-selinux/label/label_selinux.go | 48 +++++++++++++++++++
2 files changed, 54 insertions(+)

diff --git a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
index e178568..194c797 100644
--- a/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
+++ b/vendor/github.com/opencontainers/selinux/go-selinux/label/label.go
@@ -2,6 +2,12 @@

package label

+// DefaultLabels returns the process and file labels that should be used on the
+// system if nothing more specific is requested.
+func DefaultLabels() (string, string, error) {
+ return "", "", nil
+}
+
// InitLabels returns the process label and file labels to be used within
// the container. A list of options can be passed into this function to alter
// the labels.
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 2730fcf..9170521 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
@@ -23,6 +23,54 @@ var validOptions = map[string]bool{

var ErrIncompatibleLabel = fmt.Errorf("Bad SELinux option z and Z can not be used together")

+// DefaultLabels returns the process and file labels that should be used on the
+// system if nothing more specific is requested. The labels returned do not
+// need any subsequent cleanup.
+func DefaultLabels() (plabel string, mlabel string, err error) {
+ if !selinux.GetEnabled() {
+ return "", "", nil
+ }
+
+ // The labels we get back have an MCS pair, and we need to release it
+ // since the caller won't expect to handle it. The MCS pair is shared
+ // by both labels and we only need to release it once.
+ processLabelMcs, mountLabelMcs := selinux.ContainerLabels()
+ if processLabelMcs == "" {
+ return "", "", nil
+ }
+
+ defer func() {
+ if err != nil {
+ selinux.ReleaseLabel(processLabelMcs)
+ }
+ }()
+
+ // Turn the labels into structures for more convenient modification.
+ pcon, err := selinux.NewContext(processLabelMcs)
+ if err != nil {
+ return "", "", err
+ }
+
+ mcon, err := selinux.NewContext(mountLabelMcs)
+ if err != nil {
+ return "", "", err
+ }
+
+ // We've got what we need from the original labels, which is just the
+ // user, role, and type that are defined in the OS policy, so we can
+ // release the MCS pair now.
+ selinux.ReleaseLabel(processLabelMcs)
+
+ // Replace the level (which includes the MCS pair) with the default.
+ pcon["level"] = "s0"
+ mcon["level"] = "s0"
+
+ processLabel := pcon.Get()
+ mountLabel := mcon.Get()
+
+ return processLabel, mountLabel, nil
+}
+
// InitLabels returns the process label and file labels to be used within
// the container. A list of options can be passed into this function to alter
// the labels. The labels returned will include a random MCS String, that is
--
2.21.0

Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
From f62026df7b3c14b7b952630a9d4ff0e4c327d82a Mon Sep 17 00:00:00 2001
From: Ben Cressey <bcressey@amazon.com>
Date: Wed, 29 Apr 2020 15:11:37 +0000
Subject: [PATCH 2002/2002] cri: use default SELinux labels as a fallback

The transition rules in our SELinux policy give us a sensible default
for process labels, but there is no equivalent for mount labels. If
we do not supply the mount label as a context option for the mount,
the rootfs will not be writable.

By convention, the default process and mount labels are found in the
policy's lxc_contexts file, which is parsed by the SELinux module.
We use our new helper function to obtain these labels while bypassing
the MCS label pair allocation.

Signed-off-by: Ben Cressey <bcressey@amazon.com>
---
vendor/github.com/containerd/cri/pkg/server/helpers.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/vendor/github.com/containerd/cri/pkg/server/helpers.go b/vendor/github.com/containerd/cri/pkg/server/helpers.go
index 572e7b9..cfac204 100644
--- a/vendor/github.com/containerd/cri/pkg/server/helpers.go
+++ b/vendor/github.com/containerd/cri/pkg/server/helpers.go
@@ -300,14 +300,14 @@ func (c *criService) ensureImageExists(ctx context.Context, ref string, config *

func initSelinuxOpts(selinuxOpt *runtime.SELinuxOption) (string, string, error) {
if selinuxOpt == nil {
- return "", "", nil
+ return label.DefaultLabels()
}

// Should ignored selinuxOpts if they are incomplete.
if selinuxOpt.GetUser() == "" ||
selinuxOpt.GetRole() == "" ||
selinuxOpt.GetType() == "" {
- return "", "", nil
+ return label.DefaultLabels()
}

// make sure the format of "level" is correct.
--
2.21.0

4 changes: 2 additions & 2 deletions packages/containerd/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ build = "build.rs"
path = "pkg.rs"

[[package.metadata.build-package.external-files]]
url = "https://github.com/containerd/containerd/archive/v1.3.3/containerd-1.3.3.tar.gz"
sha512 = "8ec9696388c2f21def34396f0dd2432a24d55c9c1b8624e47c51a624ed1fe51fde717015cd891705438c1c317f95c5601e58ceca8b4e5d813f55ff515eb1e269"
url = "https://github.com/containerd/containerd/archive/v1.3.4/containerd-1.3.4.tar.gz"
sha512 = "b186d5aef3e5a0d35c12dcc3cfa5d48a9602f6278c4650942859a1ab6abd1299d33a1bc623376955a834a2626491196b604591d92a05d39745dfc33ff51ad5aa"

[build-dependencies]
glibc = { path = "../glibc" }
Expand Down
1 change: 1 addition & 0 deletions packages/containerd/containerd.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Wants=network-online.target configured.target

[Service]
ExecStart=/usr/bin/containerd
Type=notify
Delegate=yes
KillMode=process
TimeoutSec=0
Expand Down
15 changes: 13 additions & 2 deletions packages/containerd/containerd.spec
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
%global gorepo containerd
%global goimport %{goproject}/%{gorepo}

%global gover 1.3.3
%global gover 1.3.4
%global rpmver %{gover}

%global _dwz_low_mem_die_limit 0
Expand All @@ -19,7 +19,18 @@ Source2: containerd-config-toml_aws-k8s
Source3: containerd-config-toml_aws-dev
Source4: containerd-tmpfiles.conf
Source1000: clarify.toml
Patch1: 0001-reduce-logging-when-no-errors-have-occurred.patch

# Upstream patch; can drop when we move to v1.4.0.
Patch0001: 0001-Use-spec-s-mountLabel-when-mounting-the-rootfs.patch

# TODO: submit this upstream.
Patch1001: 1001-cri-reduce-logging-when-no-errors-have-occurred.patch

# Local patches for CRI to use the default system SELinux labels.
# TODO: these need to be reworked for the MCS changes in v1.4.0.
Patch2001: 2001-selinux-add-DefaultLabels-helper.patch
Patch2002: 2002-cri-use-default-SELinux-labels-as-a-fallback.patch

BuildRequires: git
BuildRequires: %{_cross_os}glibc-devel
BuildRequires: %{_cross_os}libseccomp-devel
Expand Down
3 changes: 2 additions & 1 deletion packages/docker-engine/daemon.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
"max-concurrent-downloads": 10,
"storage-driver": "overlay2",
"exec-opts": ["native.cgroupdriver=systemd"],
"data-root": "/var/lib/docker"
"data-root": "/var/lib/docker",
"selinux-enabled": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
From c134a9befa59fd5ab670a9c250f74cb3e4c88844 Mon Sep 17 00:00:00 2001
From: Darren Shepherd <darren@rancher.com>
Date: Mon, 24 Feb 2020 09:53:42 -0700
Subject: [PATCH] Use spec's mountLabel when mounting the rootfs

In NewContainer if a SnapshotKey is used and the spec has
a mountLabel specified, that mountLabel should be used to mount
the rootfs.

Signed-off-by: Darren Shepherd <darren@rancher.com>
---
container.go | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/container.go b/container.go
index fd880d0e..187934ea 100644
--- a/container.go
+++ b/container.go
@@ -36,6 +36,7 @@ import (
prototypes "github.com/gogo/protobuf/types"
ver "github.com/opencontainers/image-spec/specs-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
+ "github.com/opencontainers/selinux/go-selinux/label"
"github.com/pkg/errors"
)

@@ -242,7 +243,17 @@ func (c *container) NewTask(ctx context.Context, ioCreate cio.Creator, opts ...N
if err != nil {
return nil, err
}
+ spec, err := c.Spec(ctx)
+ if err != nil {
+ return nil, err
+ }
for _, m := range mounts {
+ if spec.Linux != nil && spec.Linux.MountLabel != "" {
+ context := label.FormatMountLabel("", spec.Linux.MountLabel)
+ if context != "" {
+ m.Options = append(m.Options, context)
+ }
+ }
request.Rootfs = append(request.Rootfs, &types.Mount{
Type: m.Type,
Source: m.Source,
--
2.21.0

1 change: 1 addition & 0 deletions packages/host-ctr/host-containerd.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Wants=network-online.target configured.target

[Service]
ExecStart=/usr/bin/containerd --config /etc/host-containerd/config.toml
Type=notify
Delegate=yes
KillMode=process
TimeoutSec=0
Expand Down
4 changes: 4 additions & 0 deletions packages/host-ctr/host-ctr.spec
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@ Requires: %{_cross_os}containerd
Source10: host-containerd.service
Source11: host-containerd-tmpfiles.conf
Source12: host-containerd-config.toml
Patch1: 0001-Use-spec-s-mountLabel-when-mounting-the-rootfs.patch

%description
%{summary}.

%prep
%setup -T -c
cp -r %{_builddir}/sources/%{workspace_name}/* .
pushd vendor/github.com/containerd/containerd
%patch1 -p1
popd

%build
%set_cross_go_flags
Expand Down
Loading