bpf: zero bpf_attr before initialization

When building with Clang and using structured initialization, the
bpf_attr union is not zero-padded, so the kernel misdetects it as
an unsupported extension.
zero it until Clang's behaviour matches GCC. Do not skip the test
on Github Actions anymore.
master
Luca Boccassi 2 years ago committed by Lennart Poettering
parent 91efc847dc
commit 28abf5ad34
  1. 8
      src/shared/bpf-program.c
  2. 10
      src/test/test-bpf-firewall.c

@ -76,6 +76,11 @@ int bpf_program_load_kernel(BPFProgram *p, char *log_buf, size_t log_size) {
return 0;
}
// FIXME: Clang doesn't 0-pad with structured initialization, causing
// the kernel to reject the bpf_attr as invalid. See:
// https://github.com/torvalds/linux/blob/v5.9/kernel/bpf/syscall.c#L65
// Ideally it should behave like GCC, so that we can remove these workarounds.
zero(attr);
attr = (union bpf_attr) {
.prog_type = p->prog_type,
.insns = PTR_TO_UINT64(p->instructions),
@ -101,6 +106,7 @@ int bpf_program_load_from_bpf_fs(BPFProgram *p, const char *path) {
if (p->kernel_fd >= 0) /* don't overwrite an assembled or loaded program */
return -EBUSY;
zero(attr);
attr = (union bpf_attr) {
.pathname = PTR_TO_UINT64(path),
};
@ -158,6 +164,7 @@ int bpf_program_cgroup_attach(BPFProgram *p, int type, const char *path, uint32_
if (fd < 0)
return -errno;
zero(attr);
attr = (union bpf_attr) {
.attach_type = type,
.target_fd = fd,
@ -194,6 +201,7 @@ int bpf_program_cgroup_detach(BPFProgram *p) {
} else {
union bpf_attr attr;
zero(attr);
attr = (union bpf_attr) {
.attach_type = p->attached_type,
.target_fd = fd,

@ -37,16 +37,6 @@ int main(int argc, char *argv[]) {
if (detect_container() > 0)
return log_tests_skipped("test-bpf-firewall fails inside LXC and Docker containers: https://github.com/systemd/systemd/issues/9666");
#ifdef __clang__
/* FIXME: This test is for (currently unknown) reasons failing in both
* sanitized and unsanitized clang runs. Until the issue is resolved,
* let's skip the test when running on GH Actions and compiled with
* clang.
*/
if (strstr_ptr(ci_environment(), "github-actions"))
return log_tests_skipped("Skipping test on GH Actions");
#endif
assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0);
rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE);
(void) setrlimit(RLIMIT_MEMLOCK, &rl);

Loading…
Cancel
Save