summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLuca Boccassi <bluca@debian.org>2024-05-28 19:59:24 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2024-05-29 08:29:47 +0200
commit8e495bf0b7c2c6a86ce2af9f49f888c281203eb6 (patch)
tree0f139c6bf14e88e23b385e479bd7fc2897afad19 /src
parenttest-network: update comment about status of kernel regression (diff)
downloadsystemd-8e495bf0b7c2c6a86ce2af9f49f888c281203eb6.tar.xz
systemd-8e495bf0b7c2c6a86ce2af9f49f888c281203eb6.zip
bpf: add helper to translate kernel error codes from libbpf
libbpf returns error codes from the kernel unmodified, and we don't understand them so non-fatal ones are handled as hard errors. Add a translation helper, and start by translating 524 to EOPNOTSUPP, which is returned when nsresourced tries to use LSM BPF hooks that are not implemented on a given arch (in this case, arm64 is misssing trampolines). Fixes https://github.com/systemd/systemd/issues/32170
Diffstat (limited to '')
-rw-r--r--src/core/bpf-restrict-fs.c4
-rw-r--r--src/core/bpf-restrict-ifaces.c4
-rw-r--r--src/core/bpf-socket-bind.c4
-rw-r--r--src/nsresourced/userns-restrict.c4
-rw-r--r--src/shared/bpf-dlopen.c17
-rw-r--r--src/shared/bpf-dlopen.h6
-rw-r--r--src/shared/bpf-link.c4
7 files changed, 32 insertions, 11 deletions
diff --git a/src/core/bpf-restrict-fs.c b/src/core/bpf-restrict-fs.c
index 9300c19390..d36bfb5d5e 100644
--- a/src/core/bpf-restrict-fs.c
+++ b/src/core/bpf-restrict-fs.c
@@ -51,7 +51,7 @@ static bool bpf_can_link_lsm_program(struct bpf_program *prog) {
/* 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) {
@@ -139,7 +139,7 @@ int bpf_restrict_fs_setup(Manager *m) {
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));
diff --git a/src/core/bpf-restrict-ifaces.c b/src/core/bpf-restrict-ifaces.c
index ddecd3f866..64d8d1a7e5 100644
--- a/src/core/bpf-restrict-ifaces.c
+++ b/src/core/bpf-restrict-ifaces.c
@@ -133,12 +133,12 @@ static int restrict_ifaces_install_impl(Unit *u) {
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");
diff --git a/src/core/bpf-socket-bind.c b/src/core/bpf-socket-bind.c
index 3008d8249c..2a1a0278d5 100644
--- a/src/core/bpf-socket-bind.c
+++ b/src/core/bpf-socket-bind.c
@@ -201,13 +201,13 @@ static int socket_bind_install_impl(Unit *u) {
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));
diff --git a/src/nsresourced/userns-restrict.c b/src/nsresourced/userns-restrict.c
index 241a655e62..be33f49f55 100644
--- a/src/nsresourced/userns-restrict.c
+++ b/src/nsresourced/userns-restrict.c
@@ -131,7 +131,7 @@ int userns_restrict_install(
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");
@@ -144,7 +144,7 @@ int userns_restrict_install(
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");
diff --git a/src/shared/bpf-dlopen.c b/src/shared/bpf-dlopen.c
index d4ae24053e..50491fc6aa 100644
--- a/src/shared/bpf-dlopen.c
+++ b/src/shared/bpf-dlopen.c
@@ -181,6 +181,23 @@ int dlopen_bpf(void) {
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) {
diff --git a/src/shared/bpf-dlopen.h b/src/shared/bpf-dlopen.h
index 6deca829f1..df12d08e50 100644
--- a/src/shared/bpf-dlopen.h
+++ b/src/shared/bpf-dlopen.h
@@ -35,13 +35,17 @@ DLSYM_PROTOTYPE(bpf_program__attach);
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);
diff --git a/src/shared/bpf-link.c b/src/shared/bpf-link.c
index fea49b2ecb..77f6a4ee9a 100644
--- a/src/shared/bpf-link.c
+++ b/src/shared/bpf-link.c
@@ -16,7 +16,7 @@ bool bpf_can_link_program(struct bpf_program *prog) {
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) {
@@ -25,7 +25,7 @@ int bpf_serialize_link(FILE *f, FDSet *fds, const char *key, struct bpf_link *li
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));