Skip to content
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
46 changes: 46 additions & 0 deletions src/libcrun/cgroup-systemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1668,6 +1668,28 @@ reset_failed_unit (sd_bus *bus, const char *unit)
return sd_err;
}

static int
verify_ebpf_device_filter_installed (const char *cgroup_path, libcrun_error_t *err)
{
cleanup_free uint32_t *progs = NULL;
cleanup_free char *full_path = NULL;
size_t n_progs = 0;
int ret;

ret = append_paths (&full_path, err, CGROUP_ROOT, cgroup_path, NULL);
if (UNLIKELY (ret < 0))
return ret;

ret = libcrun_ebpf_query_cgroup_progs (full_path, &progs, &n_progs, err);
if (UNLIKELY (ret < 0))
return ret;

if (n_progs == 0)
return crun_make_error (err, 0, "systemd failed to install eBPF device filter on cgroup `%s`", full_path);

return 0;
}

static int
enter_systemd_cgroup_scope (runtime_spec_schema_config_linux_resources *resources,
int cgroup_mode,
Expand Down Expand Up @@ -2023,6 +2045,30 @@ libcrun_cgroup_enter_systemd (struct libcrun_cgroup_args *args,
if (UNLIKELY (ret < 0))
return ret;

/* Verify that systemd has actually installed the eBPF device filter if one was requested. */
if (out->bpf_dev_set)
{
cleanup_free char *scope_path = NULL;

/* eBPF programs are attached to the systemd scope, not the subgroup.
Remove the suffix that was added by systemd_finalize. */
if (is_empty_string (suffix))
scope_path = xstrdup (path);
else
{
size_t path_len = strlen (path);
size_t suffix_len = strlen (suffix);

scope_path = strndup (path, path_len - suffix_len - 1);
if (UNLIKELY (scope_path == NULL))
OOM ();
}

ret = verify_ebpf_device_filter_installed (scope_path, err);
if (UNLIKELY (ret < 0))
return ret;
}

out->path = path;
path = NULL;

Expand Down
19 changes: 19 additions & 0 deletions src/libcrun/ebpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,25 @@ libcrun_ebpf_read_program (struct bpf_program **program_ret, const char *path, l
#endif
}

int
libcrun_ebpf_query_cgroup_progs (const char *cgroup_path, uint32_t **progs_out, size_t *n_progs_out, libcrun_error_t *err)
{
#ifndef HAVE_EBPF
(void) cgroup_path;
*progs_out = NULL;
*n_progs_out = 0;
return crun_make_error (err, 0, "eBPF not supported");
#else
cleanup_close int cgroup_fd = -1;

cgroup_fd = open (cgroup_path, O_RDONLY | O_CLOEXEC);
if (UNLIKELY (cgroup_fd < 0))
return crun_make_error (err, errno, "open cgroup path `%s`", cgroup_path);

return read_all_progs (cgroup_fd, progs_out, n_progs_out, err);
#endif
}

bool
libcrun_ebpf_cmp_programs (struct bpf_program *program1, struct bpf_program *program2)
{
Expand Down
1 change: 1 addition & 0 deletions src/libcrun/ebpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct bpf_program *bpf_program_complete_dev (struct bpf_program *program, libcr

int libcrun_ebpf_load (struct bpf_program *program, int dirfd, const char *pin, libcrun_error_t *err);
int libcrun_ebpf_read_program (struct bpf_program **program, const char *path, libcrun_error_t *err);
int libcrun_ebpf_query_cgroup_progs (const char *cgroup_path, uint32_t **progs_out, size_t *n_progs_out, libcrun_error_t *err);
bool libcrun_ebpf_cmp_programs (struct bpf_program *program1, struct bpf_program *program2);

#endif