SHA256
1
0
forked from pool/runc
runc/boo1187704-0001-cgroupv2-ebpf-ignore-inaccessible-existing-programs.patch

124 lines
5.4 KiB
Diff

From e54bd299f9e170fe35041c839ab90206f02e4df0 Mon Sep 17 00:00:00 2001
From: Aleksa Sarai <cyphar@cyphar.com>
Date: Thu, 1 Jul 2021 12:55:08 +1000
Subject: [PATCH] cgroupv2: ebpf: ignore inaccessible existing programs
This is necessary in order for runc to be able to configure device
cgroups with --systemd-cgroup on distributions that have very strict
SELinux policies such as openSUSE MicroOS[1].
The core issue here is that systemd is adding its own BPF policy that
has an SELinux label such that runc cannot interact with it. In order to
work around this, we can just ignore the policy -- in theory this
behaviour is not correct but given that the most obvious case
(--systemd-cgroup) will still handle updates correctly, this logic is
reasonable.
(This also contains a backport of [2].)
[1]: https://bugzilla.suse.com/show_bug.cgi?id=1182428
[2]: https://github.com/cilium/ebpf/pull/334
Fixes: d0f2c25f521e ("cgroup2: devices: replace all existing filters when attaching")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
---
go.mod | 2 ++
go.sum | 4 ++++
libcontainer/cgroups/ebpf/ebpf_linux.go | 19 ++++++++++++++++---
vendor/github.com/cilium/ebpf/syscalls.go | 5 ++---
vendor/modules.txt | 2 +-
5 files changed, 25 insertions(+), 7 deletions(-)
diff --git a/go.mod b/go.mod
index 6262a12198ca..95d14b12b36c 100644
--- a/go.mod
+++ b/go.mod
@@ -26,3 +26,5 @@ require (
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887
google.golang.org/protobuf v1.26.0
)
+
+replace github.com/cilium/ebpf => github.com/cyphar/ebpf v0.6.1-0.20210701060515-e654431ae87f
diff --git a/go.sum b/go.sum
index 0bc7fd057207..00bb16d7ff6f 100644
--- a/go.sum
+++ b/go.sum
@@ -11,6 +11,10 @@ github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzA
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cyphar/ebpf v0.6.1-0.20210701040454-26565c82f4f1 h1:Y+9BQzEwXR1yEhvf843TRwrMgwH7ZbO3arwgZfXPhFU=
+github.com/cyphar/ebpf v0.6.1-0.20210701040454-26565c82f4f1/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
+github.com/cyphar/ebpf v0.6.1-0.20210701060515-e654431ae87f h1:MqvjlbU/U6s12v7ru6MbLKIkLlzGMDiMKYi4yGHGz2Q=
+github.com/cyphar/ebpf v0.6.1-0.20210701060515-e654431ae87f/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs=
github.com/cyphar/filepath-securejoin v0.2.2 h1:jCwT2GTP+PY5nBz3c/YL5PAIbusElVrPujOBSCj8xRg=
github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
diff --git a/libcontainer/cgroups/ebpf/ebpf_linux.go b/libcontainer/cgroups/ebpf/ebpf_linux.go
index fccf3931d6ee..dd119ad4f7a5 100644
--- a/libcontainer/cgroups/ebpf/ebpf_linux.go
+++ b/libcontainer/cgroups/ebpf/ebpf_linux.go
@@ -59,13 +59,26 @@ func findAttachedCgroupDeviceFilters(dirFd int) ([]*ebpf.Program, error) {
// Convert the ids to program handles.
progIds = progIds[:size]
- programs := make([]*ebpf.Program, len(progIds))
- for idx, progId := range progIds {
+ programs := make([]*ebpf.Program, 0, len(progIds))
+ for _, progId := range progIds {
program, err := ebpf.NewProgramFromID(ebpf.ProgramID(progId))
if err != nil {
+ // We skip over programs that give us -EACCES. This is
+ // necessary because there may be BPF programs that have been
+ // attached (such as with --systemd-cgroup) which have an LSM
+ // label that blocks us from interacting with the program.
+ //
+ // Because additional BPF_CGROUP_DEVICE programs only can add
+ // restrictions, there's no real issue with just ignoring these
+ // programs (and stops runc from breaking on distributions with
+ // very strict SELinux policies).
+ if errors.Is(err, unix.EACCES) {
+ logrus.Debugf("ignoring existing CGROUP_DEVICE program (prog_id=%v) which cannot be accessed by runc -- likely due to LSM policy", progId)
+ continue
+ }
return nil, fmt.Errorf("cannot fetch program from id: %w", err)
}
- programs[idx] = program
+ programs = append(programs, program)
}
runtime.KeepAlive(progIds)
return programs, nil
diff --git a/vendor/github.com/cilium/ebpf/syscalls.go b/vendor/github.com/cilium/ebpf/syscalls.go
index c530aadd9a5b..82678eb4043d 100644
--- a/vendor/github.com/cilium/ebpf/syscalls.go
+++ b/vendor/github.com/cilium/ebpf/syscalls.go
@@ -360,10 +360,9 @@ func wrapObjError(err error) error {
return nil
}
if errors.Is(err, unix.ENOENT) {
- return fmt.Errorf("%w", ErrNotExist)
+ return ErrNotExist
}
-
- return errors.New(err.Error())
+ return err
}
func wrapMapError(err error) error {
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 6878ffcfb192..2da80d8ee4f6 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -3,7 +3,7 @@ github.com/bits-and-blooms/bitset
# github.com/checkpoint-restore/go-criu/v5 v5.0.0
github.com/checkpoint-restore/go-criu/v5
github.com/checkpoint-restore/go-criu/v5/rpc
-# github.com/cilium/ebpf v0.6.1
+# github.com/cilium/ebpf v0.6.1 => github.com/cyphar/ebpf v0.6.1-0.20210701060515-e654431ae87f
github.com/cilium/ebpf
github.com/cilium/ebpf/asm
github.com/cilium/ebpf/internal
--
2.32.0