bpf-devices: fix order of removing and adding BPF programs

The current code has multiple issues and it should never be done like
that.  If someone updates list of allowed devices we should attach new
program before we remove the old one for two reasons:

1. It takes some time to attach new program so there is a period of time
when all devices are allowed.

2. BPF programs have limit for number of instructions (4096) and if user
adds a lot of devices we might hit the instruction limit and the new
program will not be accepted which will result in allow all devices
because the old program was already removed.

In order to attach the new program before we remove the old one we need
to use BPF_F_ALLOW_MULTI flag every time.

Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
This commit is contained in:
Pavel Hrdina 2018-11-12 10:53:47 +01:00
parent 0b82cd2502
commit 2af3eed1aa
1 changed files with 4 additions and 6 deletions

View File

@ -142,7 +142,6 @@ int cgroup_apply_device_bpf(Unit *u, BPFProgram *prog, CGroupDevicePolicy policy
};
_cleanup_free_ char *path = NULL;
uint32_t flags;
int r;
if (!prog) {
@ -177,15 +176,14 @@ int cgroup_apply_device_bpf(Unit *u, BPFProgram *prog, CGroupDevicePolicy policy
if (r < 0)
return log_error_errno(r, "Failed to determine cgroup path: %m");
flags = (u->type == UNIT_SLICE || unit_cgroup_delegate(u)) ? BPF_F_ALLOW_MULTI : 0;
r = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE, path, BPF_F_ALLOW_MULTI);
if (r < 0)
return log_error_errno(r, "Attaching device control BPF program to cgroup %s failed: %m", path);
/* Unref the old BPF program (which will implicitly detach it) right before attaching the new program. */
u->bpf_device_control_installed = bpf_program_unref(u->bpf_device_control_installed);
r = bpf_program_cgroup_attach(prog, BPF_CGROUP_DEVICE, path, flags);
if (r < 0)
return log_error_errno(r, "Attaching device control BPF program to cgroup %s failed: %m", path);
/* Remember that this BPF program is installed now. */
u->bpf_device_control_installed = bpf_program_ref(prog);