Skip to content

Commit 14e99b7

Browse files
authored
Merge pull request #1865 from giuseppe/add-check-for-ebpf-load
cgroup, systemd: validate ebpf is loaded
2 parents c630cb6 + a111995 commit 14e99b7

File tree

3 files changed

+66
-0
lines changed

3 files changed

+66
-0
lines changed

src/libcrun/cgroup-systemd.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,6 +1668,28 @@ reset_failed_unit (sd_bus *bus, const char *unit)
16681668
return sd_err;
16691669
}
16701670

1671+
static int
1672+
verify_ebpf_device_filter_installed (const char *cgroup_path, libcrun_error_t *err)
1673+
{
1674+
cleanup_free uint32_t *progs = NULL;
1675+
cleanup_free char *full_path = NULL;
1676+
size_t n_progs = 0;
1677+
int ret;
1678+
1679+
ret = append_paths (&full_path, err, CGROUP_ROOT, cgroup_path, NULL);
1680+
if (UNLIKELY (ret < 0))
1681+
return ret;
1682+
1683+
ret = libcrun_ebpf_query_cgroup_progs (full_path, &progs, &n_progs, err);
1684+
if (UNLIKELY (ret < 0))
1685+
return ret;
1686+
1687+
if (n_progs == 0)
1688+
return crun_make_error (err, 0, "systemd failed to install eBPF device filter on cgroup `%s`", full_path);
1689+
1690+
return 0;
1691+
}
1692+
16711693
static int
16721694
enter_systemd_cgroup_scope (runtime_spec_schema_config_linux_resources *resources,
16731695
int cgroup_mode,
@@ -2023,6 +2045,30 @@ libcrun_cgroup_enter_systemd (struct libcrun_cgroup_args *args,
20232045
if (UNLIKELY (ret < 0))
20242046
return ret;
20252047

2048+
/* Verify that systemd has actually installed the eBPF device filter if one was requested. */
2049+
if (out->bpf_dev_set)
2050+
{
2051+
cleanup_free char *scope_path = NULL;
2052+
2053+
/* eBPF programs are attached to the systemd scope, not the subgroup.
2054+
Remove the suffix that was added by systemd_finalize. */
2055+
if (is_empty_string (suffix))
2056+
scope_path = xstrdup (path);
2057+
else
2058+
{
2059+
size_t path_len = strlen (path);
2060+
size_t suffix_len = strlen (suffix);
2061+
2062+
scope_path = strndup (path, path_len - suffix_len - 1);
2063+
if (UNLIKELY (scope_path == NULL))
2064+
OOM ();
2065+
}
2066+
2067+
ret = verify_ebpf_device_filter_installed (scope_path, err);
2068+
if (UNLIKELY (ret < 0))
2069+
return ret;
2070+
}
2071+
20262072
out->path = path;
20272073
path = NULL;
20282074

src/libcrun/ebpf.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,25 @@ libcrun_ebpf_read_program (struct bpf_program **program_ret, const char *path, l
607607
#endif
608608
}
609609

610+
int
611+
libcrun_ebpf_query_cgroup_progs (const char *cgroup_path, uint32_t **progs_out, size_t *n_progs_out, libcrun_error_t *err)
612+
{
613+
#ifndef HAVE_EBPF
614+
(void) cgroup_path;
615+
*progs_out = NULL;
616+
*n_progs_out = 0;
617+
return crun_make_error (err, 0, "eBPF not supported");
618+
#else
619+
cleanup_close int cgroup_fd = -1;
620+
621+
cgroup_fd = open (cgroup_path, O_RDONLY | O_CLOEXEC);
622+
if (UNLIKELY (cgroup_fd < 0))
623+
return crun_make_error (err, errno, "open cgroup path `%s`", cgroup_path);
624+
625+
return read_all_progs (cgroup_fd, progs_out, n_progs_out, err);
626+
#endif
627+
}
628+
610629
bool
611630
libcrun_ebpf_cmp_programs (struct bpf_program *program1, struct bpf_program *program2)
612631
{

src/libcrun/ebpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ struct bpf_program *bpf_program_complete_dev (struct bpf_program *program, libcr
4242

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

4748
#endif

0 commit comments

Comments
 (0)