Skip to content

Commit d715d00

Browse files
committed
Handle KVM based runtimes with selinux
Signed-off-by: Michael Crosby <[email protected]>
1 parent 56a89cd commit d715d00

5 files changed

Lines changed: 122 additions & 0 deletions

File tree

pkg/server/container_create.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,12 @@ func (c *criService) CreateContainer(ctx context.Context, r *runtime.CreateConta
161161
}
162162

163163
meta.ProcessLabel = spec.Process.SelinuxLabel
164+
165+
// handle any KVM based runtime
166+
if err := modifyProcessLabel(ociRuntime.Type, spec); err != nil {
167+
return nil, err
168+
}
169+
164170
if config.GetLinux().GetSecurityContext().GetPrivileged() {
165171
// If privileged don't set the SELinux label but still record it on the container so
166172
// the unused MCS label can be release later

pkg/server/helpers_unix.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ import (
3333
"github.com/containerd/containerd/log"
3434
"github.com/containerd/containerd/mount"
3535
"github.com/containerd/cri/pkg/seccomp"
36+
"github.com/containerd/cri/pkg/seutil"
3637
runcapparmor "github.com/opencontainers/runc/libcontainer/apparmor"
38+
"github.com/opencontainers/runtime-spec/specs-go"
3739
"github.com/opencontainers/selinux/go-selinux/label"
3840
"github.com/pkg/errors"
3941
"golang.org/x/sys/unix"
@@ -256,3 +258,35 @@ func ensureRemoveAll(ctx context.Context, dir string) error {
256258
time.Sleep(100 * time.Millisecond)
257259
}
258260
}
261+
262+
var vmbasedRuntimes = []string{
263+
"io.containerd.kata",
264+
}
265+
266+
func isVMBasedRuntime(runtimeType string) bool {
267+
for _, rt := range vmbasedRuntimes {
268+
if strings.Contains(runtimeType, rt) {
269+
return true
270+
}
271+
}
272+
return false
273+
}
274+
275+
func modifyProcessLabel(runtimeType string, spec *specs.Spec) error {
276+
if !isVMBasedRuntime(runtimeType) {
277+
return nil
278+
}
279+
l, err := getKVMLabel(spec.Process.SelinuxLabel)
280+
if err != nil {
281+
return errors.Wrap(err, "failed to get selinux kvm label")
282+
}
283+
spec.Process.SelinuxLabel = l
284+
return nil
285+
}
286+
287+
func getKVMLabel(l string) (string, error) {
288+
if !seutil.HasType("container_kvm_t") {
289+
return "", nil
290+
}
291+
return seutil.ChangeToKVM(l)
292+
}

pkg/server/helpers_windows.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ import (
2424
"path/filepath"
2525
"syscall"
2626
"time"
27+
28+
"github.com/opencontainers/runtime-spec/specs-go"
2729
)
2830

2931
// openLogFile opens/creates a container log file.
@@ -217,3 +219,7 @@ func ensureRemoveAll(_ context.Context, dir string) error {
217219
time.Sleep(100 * time.Millisecond)
218220
}
219221
}
222+
223+
func modifyProcessLabel(runtimeType string, spec *specs.Spec) error {
224+
return nil
225+
}

pkg/server/sandbox_run.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ func (c *criService) RunPodSandbox(ctx context.Context, r *runtime.RunPodSandbox
167167
}
168168
}()
169169

170+
// handle any KVM based runtime
171+
if err := modifyProcessLabel(ociRuntime.Type, spec); err != nil {
172+
return nil, err
173+
}
174+
170175
if config.GetLinux().GetSecurityContext().GetPrivileged() {
171176
// If privileged don't set selinux label, but we still record the MCS label so that
172177
// the unused label can be freed later.

pkg/seutil/seutil.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
Copyright The containerd Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package seutil
18+
19+
import (
20+
"bufio"
21+
"os"
22+
23+
"github.com/opencontainers/selinux/go-selinux"
24+
)
25+
26+
var seTypes map[string]struct{}
27+
28+
const typePath = "/etc/selinux/targeted/contexts/customizable_types"
29+
30+
func init() {
31+
seTypes = make(map[string]struct{})
32+
if !selinux.GetEnabled() {
33+
return
34+
}
35+
f, err := os.Open(typePath)
36+
if err != nil {
37+
return
38+
}
39+
defer f.Close()
40+
s := bufio.NewScanner(f)
41+
for s.Scan() {
42+
seTypes[s.Text()] = struct{}{}
43+
}
44+
}
45+
46+
// HasType returns true if the underlying system has the
47+
// provided selinux type enabled.
48+
func HasType(name string) bool {
49+
_, ok := seTypes[name]
50+
return ok
51+
}
52+
53+
// ChangeToKVM process label
54+
func ChangeToKVM(l string) (string, error) {
55+
if l == "" || !selinux.GetEnabled() {
56+
return "", nil
57+
}
58+
proc, _ := selinux.KVMContainerLabels()
59+
selinux.ReleaseLabel(proc)
60+
61+
current, err := selinux.NewContext(l)
62+
if err != nil {
63+
return "", err
64+
}
65+
next, err := selinux.NewContext(proc)
66+
if err != nil {
67+
return "", err
68+
}
69+
current["type"] = next["type"]
70+
return current.Get(), nil
71+
}

0 commit comments

Comments
 (0)