/* If bpf_program__attach_lsm fails the resulting value stores libbpf error code instead of memory
* pointer. That is the case when the helper is called on architectures where BPF trampoline (hence
* BPF_LSM_MAC attach type) is not supported. */
- return sym_libbpf_get_error(link) == 0;
+ return bpf_get_error_translated(link) == 0;
}
static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) {
return r;
link = sym_bpf_program__attach_lsm(obj->progs.restrict_filesystems);
- r = sym_libbpf_get_error(link);
+ r = bpf_get_error_translated(link);
if (r != 0)
return log_error_errno(r, "bpf-restrict-fs: Failed to link '%s' LSM BPF program: %m",
sym_bpf_program__name(obj->progs.restrict_filesystems));
return -errno;
ingress_link = sym_bpf_program__attach_cgroup(obj->progs.sd_restrictif_i, cgroup_fd);
- r = sym_libbpf_get_error(ingress_link);
+ r = bpf_get_error_translated(ingress_link);
if (r != 0)
return log_unit_error_errno(u, r, "restrict-interfaces: Failed to create ingress cgroup link: %m");
egress_link = sym_bpf_program__attach_cgroup(obj->progs.sd_restrictif_e, cgroup_fd);
- r = sym_libbpf_get_error(egress_link);
+ r = bpf_get_error_translated(egress_link);
if (r != 0)
return log_unit_error_errno(u, r, "restrict-interfaces: Failed to create egress cgroup link: %m");
return log_unit_error_errno(u, errno, "bpf-socket-bind: Failed to open cgroup %s for reading: %m", cgroup_path);
ipv4 = sym_bpf_program__attach_cgroup(obj->progs.sd_bind4, cgroup_fd);
- r = sym_libbpf_get_error(ipv4);
+ r = bpf_get_error_translated(ipv4);
if (r != 0)
return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to link '%s' cgroup-bpf program: %m",
sym_bpf_program__name(obj->progs.sd_bind4));
ipv6 = sym_bpf_program__attach_cgroup(obj->progs.sd_bind6, cgroup_fd);
- r = sym_libbpf_get_error(ipv6);
+ r = bpf_get_error_translated(ipv6);
if (r != 0)
return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to link '%s' cgroup-bpf program: %m",
sym_bpf_program__name(obj->progs.sd_bind6));
return log_oom();
link = sym_bpf_link__open(fn);
- r = sym_libbpf_get_error(link);
+ r = bpf_get_error_translated(link);
if (r < 0) {
if (r != -ENOENT)
return log_error_errno(r, "Unable to open pinned program link: %m");
if (!link) {
link = sym_bpf_program__attach(*ps->prog);
- r = sym_libbpf_get_error(link);
+ r = bpf_get_error_translated(link);
if (r < 0)
return log_error_errno(r, "Failed to attach LSM BPF program: %m");
return r;
}
+int bpf_get_error_translated(const void *ptr) {
+ int r;
+
+ r = sym_libbpf_get_error(ptr);
+
+ switch (r) {
+ case -524:
+ /* Workaround for kernel bug, BPF returns an internal error instead of translating it, until
+ * it is fixed:
+ * https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/include/linux/errno.h?h=v6.9&id=a38297e3fb012ddfa7ce0321a7e5a8daeb1872b6#n27
+ */
+ return -EOPNOTSUPP;
+ default:
+ return r;
+ }
+}
+
#else
int dlopen_bpf(void) {
DLSYM_PROTOTYPE(bpf_program__attach_cgroup);
DLSYM_PROTOTYPE(bpf_program__attach_lsm);
DLSYM_PROTOTYPE(bpf_program__name);
-DLSYM_PROTOTYPE(libbpf_get_error);
DLSYM_PROTOTYPE(libbpf_set_print);
DLSYM_PROTOTYPE(ring_buffer__epoll_fd);
DLSYM_PROTOTYPE(ring_buffer__free);
DLSYM_PROTOTYPE(ring_buffer__new);
DLSYM_PROTOTYPE(ring_buffer__poll);
+/* libbpf sometimes returns error codes that make sense only in the kernel, like 524 for EOPNOTSUPP. Use
+ * this helper instead of libbpf_get_error() to ensure some of the known ones are translated into errnos
+ * we understand. */
+int bpf_get_error_translated(const void *ptr);
+
#endif
int dlopen_bpf(void);
link = sym_bpf_program__attach_cgroup(prog, /*cgroup_fd=*/-1);
/* EBADF indicates that bpf_link is supported by kernel. */
- return sym_libbpf_get_error(link) == -EBADF;
+ return bpf_get_error_translated(link) == -EBADF;
}
int bpf_serialize_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *link) {
if (!link)
return -ENOENT;
- if (sym_libbpf_get_error(link) != 0)
+ if (bpf_get_error_translated(link) != 0)
return -EINVAL;
return serialize_fd(f, fds, key, sym_bpf_link__fd(link));