Skip to content

Commit

Permalink
cgroupv2: ebpf: ignore inaccessible existing programs
Browse files Browse the repository at this point in the history
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.

[1]: https://bugzilla.suse.com/show_bug.cgi?id=1182428

Fixes: d0f2c25 ("cgroup2: devices: replace all existing filters when attaching")
Signed-off-by: Aleksa Sarai <cyphar@cyphar.com>
(cherry picked from commit 57e3c54)
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
  • Loading branch information
cyphar authored and kolyshkin committed Jul 14, 2021
1 parent 01b5339 commit 9389a44
Showing 1 changed file with 16 additions and 3 deletions.
19 changes: 16 additions & 3 deletions libcontainer/cgroups/ebpf/ebpf_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 or -EPERM. 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, os.ErrPermission) {
logrus.Debugf("ignoring existing CGROUP_DEVICE program (prog_id=%v) which cannot be accessed by runc -- likely due to LSM policy: %v", progId, err)
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
Expand Down

0 comments on commit 9389a44

Please sign in to comment.