From 2e09b2235a27df3ada3542a2402b6e1727fc2c6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 1 Jun 2022 17:49:27 +0200 Subject: [PATCH 1/8] various: add %m in messages Sometimes we want to suppress strerror() message because the are providing something better. But in those cases, it seems it was just forgotten. --- src/core/bpf-lsm.c | 2 +- src/userdb/userwork.c | 2 +- src/volatile-root/volatile-root.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/bpf-lsm.c b/src/core/bpf-lsm.c index d3e92b98a6..46fc8c8d3b 100644 --- a/src/core/bpf-lsm.c +++ b/src/core/bpf-lsm.c @@ -83,7 +83,7 @@ static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) { r = restrict_fs_bpf__load(obj); assert(r <= 0); if (r < 0) - return log_error_errno(r, "Failed to load BPF object"); + return log_error_errno(r, "Failed to load BPF object: %m"); *ret_obj = TAKE_PTR(obj); diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c index 18d58c308c..490e42b014 100644 --- a/src/userdb/userwork.c +++ b/src/userdb/userwork.c @@ -556,7 +556,7 @@ static int run(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parent already died?"); if (kill(parent, SIGUSR2) < 0) - return log_error_errno(errno, "Failed to kill our own parent."); + return log_error_errno(errno, "Failed to kill our own parent: %m"); } } diff --git a/src/volatile-root/volatile-root.c b/src/volatile-root/volatile-root.c index aa16582d9e..e29d4df692 100644 --- a/src/volatile-root/volatile-root.c +++ b/src/volatile-root/volatile-root.c @@ -127,7 +127,7 @@ static int run(int argc, char *argv[]) { r = query_volatile_mode(&m); if (r < 0) - return log_error_errno(r, "Failed to determine volatile mode from kernel command line."); + return log_error_errno(r, "Failed to determine volatile mode from kernel command line: %m"); if (r == 0 && argc >= 2) { /* The kernel command line always wins. However if nothing was set there, the argument passed here wins instead. */ m = volatile_mode_from_string(argv[1]); From c6cb9d90742e619062aa357c4cd0fa40bedb9773 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 1 Jun 2022 17:49:58 +0200 Subject: [PATCH 2/8] userwork: use a better errno value ESRCH is literally "No such process". --- src/userdb/userwork.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/userdb/userwork.c b/src/userdb/userwork.c index 490e42b014..21a869df1b 100644 --- a/src/userdb/userwork.c +++ b/src/userdb/userwork.c @@ -553,7 +553,7 @@ static int run(int argc, char *argv[]) { parent = getppid(); if (parent <= 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Parent already died?"); + return log_error_errno(SYNTHETIC_ERRNO(ESRCH), "Parent already died?"); if (kill(parent, SIGUSR2) < 0) return log_error_errno(errno, "Failed to kill our own parent: %m"); From 386b8026e53fee454dee5d0215abfc57b51d5757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 1 Jun 2022 23:58:28 +0200 Subject: [PATCH 3/8] meson: use files() for libcore_sources too C.f. f1b98127ff6320648cc3dc876f3b6a5aa3af204b. --- src/core/meson.build | 268 +++++++++++++++++++++---------------------- 1 file changed, 134 insertions(+), 134 deletions(-) diff --git a/src/core/meson.build b/src/core/meson.build index 1e8b6dc310..052844c8bf 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -1,139 +1,139 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -libcore_sources = ''' - apparmor-setup.c - apparmor-setup.h - audit-fd.c - audit-fd.h - automount.c - automount.h - bpf-devices.c - bpf-devices.h - bpf-firewall.c - bpf-firewall.h - bpf-foreign.c - bpf-foreign.h - bpf-lsm.c - bpf-lsm.h - bpf-socket-bind.c - bpf-socket-bind.h - cgroup.c - cgroup.h - core-varlink.c - core-varlink.h - dbus-automount.c - dbus-automount.h - dbus-cgroup.c - dbus-cgroup.h - dbus-device.c - dbus-device.h - dbus-execute.c - dbus-execute.h - dbus-job.c - dbus-job.h - dbus-kill.c - dbus-kill.h - dbus-manager.c - dbus-manager.h - dbus-mount.c - dbus-mount.h - dbus-path.c - dbus-path.h - dbus-scope.c - dbus-scope.h - dbus-service.c - dbus-service.h - dbus-slice.c - dbus-slice.h - dbus-socket.c - dbus-socket.h - dbus-swap.c - dbus-swap.h - dbus-target.c - dbus-target.h - dbus-timer.c - dbus-timer.h - dbus-unit.c - dbus-unit.h - dbus-util.c - dbus-util.h - dbus.c - dbus.h - device.c - device.h - dynamic-user.c - dynamic-user.h - efi-random.c - efi-random.h - emergency-action.c - emergency-action.h - execute.c - execute.h - generator-setup.c - generator-setup.h - ima-setup.c - ima-setup.h - import-creds.c - import-creds.h - job.c - job.h - kill.c - kill.h - kmod-setup.c - kmod-setup.h - load-dropin.c - load-dropin.h - load-fragment.c - load-fragment.h - locale-setup.c - locale-setup.h - manager-dump.c - manager-dump.h - manager-serialize.c - manager-serialize.h - manager.c - manager.h - mount.c - mount.h - namespace.c - namespace.h - path.c - path.h - restrict-ifaces.c - restrict-ifaces.h - scope.c - scope.h - selinux-access.c - selinux-access.h - selinux-setup.c - selinux-setup.h - service.c - service.h - show-status.c - show-status.h - slice.c - slice.h - smack-setup.c - smack-setup.h - socket.c - socket.h - swap.c - swap.h - target.c - target.h - timer.c - timer.h - transaction.c - transaction.h - unit-dependency-atom.c - unit-dependency-atom.h - unit-printf.c - unit-printf.h - unit-serialize.c - unit-serialize.h - unit.c - unit.h -'''.split() +libcore_sources = files( + 'apparmor-setup.c', + 'apparmor-setup.h', + 'audit-fd.c', + 'audit-fd.h', + 'automount.c', + 'automount.h', + 'bpf-devices.c', + 'bpf-devices.h', + 'bpf-firewall.c', + 'bpf-firewall.h', + 'bpf-foreign.c', + 'bpf-foreign.h', + 'bpf-lsm.c', + 'bpf-lsm.h', + 'bpf-socket-bind.c', + 'bpf-socket-bind.h', + 'cgroup.c', + 'cgroup.h', + 'core-varlink.c', + 'core-varlink.h', + 'dbus-automount.c', + 'dbus-automount.h', + 'dbus-cgroup.c', + 'dbus-cgroup.h', + 'dbus-device.c', + 'dbus-device.h', + 'dbus-execute.c', + 'dbus-execute.h', + 'dbus-job.c', + 'dbus-job.h', + 'dbus-kill.c', + 'dbus-kill.h', + 'dbus-manager.c', + 'dbus-manager.h', + 'dbus-mount.c', + 'dbus-mount.h', + 'dbus-path.c', + 'dbus-path.h', + 'dbus-scope.c', + 'dbus-scope.h', + 'dbus-service.c', + 'dbus-service.h', + 'dbus-slice.c', + 'dbus-slice.h', + 'dbus-socket.c', + 'dbus-socket.h', + 'dbus-swap.c', + 'dbus-swap.h', + 'dbus-target.c', + 'dbus-target.h', + 'dbus-timer.c', + 'dbus-timer.h', + 'dbus-unit.c', + 'dbus-unit.h', + 'dbus-util.c', + 'dbus-util.h', + 'dbus.c', + 'dbus.h', + 'device.c', + 'device.h', + 'dynamic-user.c', + 'dynamic-user.h', + 'efi-random.c', + 'efi-random.h', + 'emergency-action.c', + 'emergency-action.h', + 'execute.c', + 'execute.h', + 'generator-setup.c', + 'generator-setup.h', + 'ima-setup.c', + 'ima-setup.h', + 'import-creds.c', + 'import-creds.h', + 'job.c', + 'job.h', + 'kill.c', + 'kill.h', + 'kmod-setup.c', + 'kmod-setup.h', + 'load-dropin.c', + 'load-dropin.h', + 'load-fragment.c', + 'load-fragment.h', + 'locale-setup.c', + 'locale-setup.h', + 'manager-dump.c', + 'manager-dump.h', + 'manager-serialize.c', + 'manager-serialize.h', + 'manager.c', + 'manager.h', + 'mount.c', + 'mount.h', + 'namespace.c', + 'namespace.h', + 'path.c', + 'path.h', + 'restrict-ifaces.c', + 'restrict-ifaces.h', + 'scope.c', + 'scope.h', + 'selinux-access.c', + 'selinux-access.h', + 'selinux-setup.c', + 'selinux-setup.h', + 'service.c', + 'service.h', + 'show-status.c', + 'show-status.h', + 'slice.c', + 'slice.h', + 'smack-setup.c', + 'smack-setup.h', + 'socket.c', + 'socket.h', + 'swap.c', + 'swap.h', + 'target.c', + 'target.h', + 'timer.c', + 'timer.h', + 'transaction.c', + 'transaction.h', + 'unit-dependency-atom.c', + 'unit-dependency-atom.h', + 'unit-printf.c', + 'unit-printf.h', + 'unit-serialize.c', + 'unit-serialize.h', + 'unit.c', + 'unit.h', +) subdir('bpf') From 44005a5778ca66848bf7e8dfe4c51ae62919bd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 2 Jun 2022 00:27:52 +0200 Subject: [PATCH 4/8] shared/bpf: install log callback and suppress most messages from libbpf $ build/test-socket-bind ... libbpf: load bpf program failed: Operation not permitted libbpf: failed to load program 'sd_bind4' libbpf: failed to load object 'socket_bind_bpf' libbpf: failed to load BPF skeleton 'socket_bind_bpf': -1 Failed to load BPF object: Operation not permitted Now all lines with "libbpf:" are at debug level and will be hidden by default. Partially fixes https://bugzilla.redhat.com/show_bug.cgi?id=2084955#c14 (i.e. the error that was exposed when the initial error was fixed.) --- src/shared/bpf-dlopen.c | 28 ++++++++++++++++++++++++++-- src/shared/bpf-dlopen.h | 3 ++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/shared/bpf-dlopen.c b/src/shared/bpf-dlopen.c index 6f82002ff8..d8e778794c 100644 --- a/src/shared/bpf-dlopen.c +++ b/src/shared/bpf-dlopen.c @@ -9,7 +9,6 @@ static void *bpf_dl = NULL; struct bpf_link* (*sym_bpf_program__attach_cgroup)(struct bpf_program *, int); struct bpf_link* (*sym_bpf_program__attach_lsm)(struct bpf_program *); -long (*sym_libbpf_get_error)(const void *); int (*sym_bpf_link__fd)(const struct bpf_link *); int (*sym_bpf_link__destroy)(struct bpf_link *); int (*sym_bpf_map__fd)(const struct bpf_map *); @@ -26,9 +25,27 @@ void (*sym_bpf_object__detach_skeleton)(struct bpf_object_skeleton *); void (*sym_bpf_object__destroy_skeleton)(struct bpf_object_skeleton *); bool (*sym_bpf_probe_prog_type)(enum bpf_prog_type, __u32); const char* (*sym_bpf_program__name)(const struct bpf_program *); +libbpf_print_fn_t (*sym_libbpf_set_print)(libbpf_print_fn_t); +long (*sym_libbpf_get_error)(const void *); + +_printf_(2,0) +static int bpf_print_func(enum libbpf_print_level level, const char *fmt, va_list ap) { +#if !LOG_TRACE + /* libbpf logs a lot of details at its debug level, which we don't need to see. */ + if (level == LIBBPF_DEBUG) + return 0; +#endif + /* All other levels are downgraded to LOG_DEBUG */ + + /* errno is used here, on the assumption that if the log message uses %m, errno will be set to + * something useful. Otherwise, it shouldn't matter, we may pass 0 or some bogus value. */ + return log_internalv(LOG_DEBUG, errno, NULL, 0, NULL, fmt, ap); +} int dlopen_bpf(void) { - return dlopen_many_sym_or_warn( + int r; + + r = dlopen_many_sym_or_warn( &bpf_dl, "libbpf.so.0", LOG_DEBUG, DLSYM_ARG(bpf_link__destroy), DLSYM_ARG(bpf_link__fd), @@ -48,7 +65,14 @@ int dlopen_bpf(void) { DLSYM_ARG(bpf_program__attach_cgroup), DLSYM_ARG(bpf_program__attach_lsm), DLSYM_ARG(bpf_program__name), + DLSYM_ARG(libbpf_set_print), DLSYM_ARG(libbpf_get_error)); + if (r < 0) + return r; + + /* We set the print helper unconditionally. Otherwise libbpf will emit not useful log messages. */ + (void) sym_libbpf_set_print(bpf_print_func); + return r; } #else diff --git a/src/shared/bpf-dlopen.h b/src/shared/bpf-dlopen.h index 713c41c3f4..f0d40325d9 100644 --- a/src/shared/bpf-dlopen.h +++ b/src/shared/bpf-dlopen.h @@ -8,7 +8,6 @@ extern struct bpf_link* (*sym_bpf_program__attach_cgroup)(struct bpf_program *, int); extern struct bpf_link* (*sym_bpf_program__attach_lsm)(struct bpf_program *); -extern long (*sym_libbpf_get_error)(const void *); extern int (*sym_bpf_link__fd)(const struct bpf_link *); extern int (*sym_bpf_link__destroy)(struct bpf_link *); extern int (*sym_bpf_map__fd)(const struct bpf_map *); @@ -27,6 +26,8 @@ extern void (*sym_bpf_object__detach_skeleton)(struct bpf_object_skeleton *); extern void (*sym_bpf_object__destroy_skeleton)(struct bpf_object_skeleton *); extern bool (*sym_bpf_probe_prog_type)(enum bpf_prog_type, __u32); extern const char* (*sym_bpf_program__name)(const struct bpf_program *); +extern libbpf_print_fn_t (*sym_libbpf_set_print)(libbpf_print_fn_t); +extern long (*sym_libbpf_get_error)(const void *); #endif From b1fdcda8765b0f3c059e90b152c13c9797bc9814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 2 Jun 2022 00:38:14 +0200 Subject: [PATCH 5/8] tests: drop pointless checks for root Testing the error paths is very important. If we are not root, we should try and get a failure, which we should report nicely and mark the test as skipped. After those checks are removed, this is what seems to happen. This way we can see what will happen e.g. in the user manager when we try to perform some bpf ops. --- src/test/test-bpf-firewall.c | 3 --- src/test/test-bpf-lsm.c | 3 --- src/test/test-socket-bind.c | 3 --- 3 files changed, 9 deletions(-) diff --git a/src/test/test-bpf-firewall.c b/src/test/test-bpf-firewall.c index 8f4b485073..3b99c5aaec 100644 --- a/src/test/test-bpf-firewall.c +++ b/src/test/test-bpf-firewall.c @@ -61,9 +61,6 @@ int main(int argc, char *argv[]) { r = bpf_program_add_instructions(p, exit_insn, ELEMENTSOF(exit_insn)); assert_se(r == 0); - if (getuid() != 0) - return log_tests_skipped("not running as root"); - r = bpf_firewall_supported(); if (r == BPF_FIREWALL_UNSUPPORTED) return log_tests_skipped("BPF firewalling not supported"); diff --git a/src/test/test-bpf-lsm.c b/src/test/test-bpf-lsm.c index 630d60dbf5..9709053d0a 100644 --- a/src/test/test-bpf-lsm.c +++ b/src/test/test-bpf-lsm.c @@ -68,9 +68,6 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); - if (getuid() != 0) - return log_tests_skipped("not running as root"); - assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0); rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE); (void) setrlimit_closest(RLIMIT_MEMLOCK, &rl); diff --git a/src/test/test-socket-bind.c b/src/test/test-socket-bind.c index 59d8cc965b..fd1fc7a26b 100644 --- a/src/test/test-socket-bind.c +++ b/src/test/test-socket-bind.c @@ -110,9 +110,6 @@ int main(int argc, char *argv[]) { if (detect_container() > 0) return log_tests_skipped("test-bpf fails inside LXC and Docker containers: https://github.com/systemd/systemd/issues/9666"); - if (getuid() != 0) - return log_tests_skipped("not running as root"); - assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0); rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE); (void) setrlimit_closest(RLIMIT_MEMLOCK, &rl); From 62b045b45c795cc4d848a7d075a0b79301976bb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 2 Jun 2022 00:40:33 +0200 Subject: [PATCH 6/8] test-socket-bind: fix comment --- src/test/test-socket-bind.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test-socket-bind.c b/src/test/test-socket-bind.c index fd1fc7a26b..dadd2c0dff 100644 --- a/src/test/test-socket-bind.c +++ b/src/test/test-socket-bind.c @@ -108,7 +108,7 @@ int main(int argc, char *argv[]) { test_setup_logging(LOG_DEBUG); if (detect_container() > 0) - return log_tests_skipped("test-bpf fails inside LXC and Docker containers: https://github.com/systemd/systemd/issues/9666"); + return log_tests_skipped("test-socket-bind fails inside LXC and Docker containers: https://github.com/systemd/systemd/issues/9666"); assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0); rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE); @@ -122,7 +122,7 @@ int main(int argc, char *argv[]) { return log_tests_skipped("socket-bind is not supported"); if (find_netcat_executable(&netcat_path) != 0) - return log_tests_skipped("Can not find netcat executable"); + return log_tests_skipped("Cannot find netcat executable"); r = enter_cgroup_subroot(NULL); if (r == -ENOMEDIUM) From bb0b01ed20436a6322f8b59b19b0b5b98a6ac2bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 1 Jun 2022 23:56:25 +0200 Subject: [PATCH 7/8] core: define a helper function for basic bpf checks --- src/core/bpf-lsm.c | 18 ++---------------- src/core/bpf-socket-bind.c | 13 +++---------- src/core/bpf-util.c | 34 ++++++++++++++++++++++++++++++++++ src/core/bpf-util.h | 5 +++++ src/core/meson.build | 7 +++++++ src/core/restrict-ifaces.c | 20 ++++++-------------- 6 files changed, 57 insertions(+), 40 deletions(-) create mode 100644 src/core/bpf-util.c create mode 100644 src/core/bpf-util.h diff --git a/src/core/bpf-lsm.c b/src/core/bpf-lsm.c index 46fc8c8d3b..3ebc2fd166 100644 --- a/src/core/bpf-lsm.c +++ b/src/core/bpf-lsm.c @@ -26,6 +26,7 @@ /* libbpf, clang and llc compile time dependencies are satisfied */ #include "bpf-dlopen.h" #include "bpf-link.h" +#include "bpf-util.h" #include "bpf/restrict_fs/restrict-fs-skel.h" #define CGROUP_HASH_SIZE_MAX 2048 @@ -135,23 +136,8 @@ bool lsm_bpf_supported(bool initialize) { if (!initialize) return false; - r = dlopen_bpf(); - if (r < 0) { - log_info_errno(r, "Failed to open libbpf, LSM BPF is not supported: %m"); + if (!cgroup_bpf_supported()) return (supported = false); - } - - r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); - if (r < 0) { - log_warning_errno(r, "Can't determine whether the unified hierarchy is used: %m"); - return (supported = false); - } - - if (r == 0) { - log_info_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "Not running with unified cgroup hierarchy, LSM BPF is not supported"); - return (supported = false); - } r = mac_bpf_use(); if (r < 0) { diff --git a/src/core/bpf-socket-bind.c b/src/core/bpf-socket-bind.c index 09f83dc667..2000c5029b 100644 --- a/src/core/bpf-socket-bind.c +++ b/src/core/bpf-socket-bind.c @@ -11,8 +11,9 @@ /* libbpf, clang, llvm and bpftool compile time dependencies are satisfied */ #include "bpf-dlopen.h" #include "bpf-link.h" -#include "bpf/socket_bind/socket-bind-skel.h" +#include "bpf-util.h" #include "bpf/socket_bind/socket-bind-api.bpf.h" +#include "bpf/socket_bind/socket-bind-skel.h" static struct socket_bind_bpf *socket_bind_bpf_free(struct socket_bind_bpf *obj) { /* socket_bind_bpf__destroy handles object == NULL case */ @@ -116,15 +117,7 @@ int bpf_socket_bind_supported(void) { _cleanup_(socket_bind_bpf_freep) struct socket_bind_bpf *obj = NULL; int r; - r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); - if (r < 0) - return log_debug_errno(r, "Can't determine whether the unified hierarchy is used: %m"); - if (r == 0) { - log_debug("Not running with unified cgroup hierarchy, BPF is not supported"); - return false; - } - - if (dlopen_bpf() < 0) + if (!cgroup_bpf_supported()) return false; if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, /*ifindex=*/0)) { diff --git a/src/core/bpf-util.c b/src/core/bpf-util.c new file mode 100644 index 0000000000..9130aa373f --- /dev/null +++ b/src/core/bpf-util.c @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "bpf-dlopen.h" +#include "bpf-util.h" +#include "cgroup-util.h" +#include "log.h" + +bool cgroup_bpf_supported(void) { + static int supported = -1; + int r; + + if (supported >= 0) + return supported; + + r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); + if (r < 0) { + log_warning_errno(r, "Can't determine whether the unified hierarchy is used: %m"); + return (supported = false); + } + + if (r == 0) { + log_info_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "Not running with unified cgroup hierarchy, disabling cgroup BPF features."); + return (supported = false); + } + + r = dlopen_bpf(); + if (r < 0) { + log_info_errno(r, "Failed to open libbpf, cgroup BPF features disabled: %m"); + return (supported = false); + } + + return (supported = true); +} diff --git a/src/core/bpf-util.h b/src/core/bpf-util.h new file mode 100644 index 0000000000..a6c55cd7e5 --- /dev/null +++ b/src/core/bpf-util.h @@ -0,0 +1,5 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include + +bool cgroup_bpf_supported(void); diff --git a/src/core/meson.build b/src/core/meson.build index 052844c8bf..d7ac4e59a8 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -135,6 +135,13 @@ libcore_sources = files( 'unit.h', ) +if conf.get('BPF_FRAMEWORK') == 1 + libcore_sources += files( + 'bpf-util.c', + 'bpf-util.h', + ) +endif + subdir('bpf') subdir('bpf/socket_bind') diff --git a/src/core/restrict-ifaces.c b/src/core/restrict-ifaces.c index efa5c8d85a..a3d9985418 100644 --- a/src/core/restrict-ifaces.c +++ b/src/core/restrict-ifaces.c @@ -9,7 +9,7 @@ #include "bpf-dlopen.h" #include "bpf-link.h" - +#include "bpf-util.h" #include "bpf/restrict_ifaces/restrict-ifaces-skel.h" static struct restrict_ifaces_bpf *restrict_ifaces_bpf_free(struct restrict_ifaces_bpf *obj) { @@ -78,29 +78,21 @@ int restrict_network_interfaces_supported(void) { if (supported >= 0) return supported; - r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); - if (r < 0) - return log_error_errno(r, "Can't determine whether the unified hierarchy is used: %m"); - if (r == 0) { - log_debug("Not running with unified cgroup hierarchy, BPF is not supported"); - return supported = 0; - } - - if (dlopen_bpf() < 0) - return false; + if (!cgroup_bpf_supported()) + return (supported = false); if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SKB, /*ifindex=*/0)) { log_debug("BPF program type cgroup_skb is not supported"); - return supported = 0; + return (supported = false); } r = prepare_restrict_ifaces_bpf(NULL, true, NULL, &obj); if (r < 0) { log_debug_errno(r, "Failed to load BPF object: %m"); - return supported = 0; + return (supported = false); } - return supported = bpf_can_link_program(obj->progs.sd_restrictif_i); + return (supported = bpf_can_link_program(obj->progs.sd_restrictif_i)); } static int restrict_network_interfaces_install_impl(Unit *u) { From b1acbc08e29cf92ebff3d3e726474c9d642f6d32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 2 Jun 2022 11:15:35 +0200 Subject: [PATCH 8/8] core/bpf: prefix log messages from different bpf subsystems When something goes awry, we would get identical log messages from all the bpf subsystems. E.g. "Failed to load BPF object: %m" appeared 5 times in the sources. But it is very important to know *which* object we failed to load. This could be guessed, e.g. from surroudning messages or from filename/line metadata, but when we get log messages in bug reports, this might not be available. Let's make the messages distinguishable. While at it, some messages were adjusted a bit. In particular, we shouldn't use internal names like BPFProgram which have no meaning outside of the codebase. --- src/core/bpf-firewall.c | 64 +++++++++++++++++++++----------------- src/core/bpf-foreign.c | 22 ++++++------- src/core/bpf-lsm.c | 52 +++++++++++++++---------------- src/core/bpf-socket-bind.c | 35 +++++++++++---------- src/core/restrict-ifaces.c | 27 +++++++++------- 5 files changed, 105 insertions(+), 95 deletions(-) diff --git a/src/core/bpf-firewall.c b/src/core/bpf-firewall.c index 258d09dd45..ce3b76c512 100644 --- a/src/core/bpf-firewall.c +++ b/src/core/bpf-firewall.c @@ -543,7 +543,7 @@ int bpf_firewall_compile(Unit *u) { return supported; if (supported == BPF_FIREWALL_UNSUPPORTED) return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), - "BPF firewalling not supported on this manager, proceeding without."); + "bpf-firewall: BPF firewalling not supported, proceeding without."); if (supported != BPF_FIREWALL_SUPPORTED_WITH_MULTI && u->type == UNIT_SLICE) /* If BPF_F_ALLOW_MULTI is not supported we don't support any BPF magic on inner nodes (i.e. on slice * units), since that would mean leaf nodes couldn't do any BPF anymore at all. Under the assumption @@ -551,7 +551,7 @@ int bpf_firewall_compile(Unit *u) { * consistent with old systemd behaviour from before v238, where BPF wasn't supported in inner nodes at * all, either. */ return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), - "BPF_F_ALLOW_MULTI is not supported on this manager, not doing BPF firewall on slice units."); + "bpf-firewall: BPF_F_ALLOW_MULTI is not supported, not doing BPF firewall on slice units."); /* If BPF_F_ALLOW_MULTI flag is supported program name is also supported (both were added to v4.15 * kernel). */ @@ -582,24 +582,24 @@ int bpf_firewall_compile(Unit *u) { r = bpf_firewall_prepare_access_maps(u, ACCESS_ALLOWED, &u->ipv4_allow_map_fd, &u->ipv6_allow_map_fd, &ip_allow_any); if (r < 0) - return log_unit_error_errno(u, r, "Preparation of eBPF allow maps failed: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Preparation of BPF allow maps failed: %m"); r = bpf_firewall_prepare_access_maps(u, ACCESS_DENIED, &u->ipv4_deny_map_fd, &u->ipv6_deny_map_fd, &ip_deny_any); if (r < 0) - return log_unit_error_errno(u, r, "Preparation of eBPF deny maps failed: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Preparation of BPF deny maps failed: %m"); } r = bpf_firewall_prepare_accounting_maps(u, cc->ip_accounting, &u->ip_accounting_ingress_map_fd, &u->ip_accounting_egress_map_fd); if (r < 0) - return log_unit_error_errno(u, r, "Preparation of eBPF accounting maps failed: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Preparation of BPF accounting maps failed: %m"); r = bpf_firewall_compile_bpf(u, ingress_name, true, &u->ip_bpf_ingress, ip_allow_any, ip_deny_any); if (r < 0) - return log_unit_error_errno(u, r, "Compilation for ingress BPF program failed: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Compilation of ingress BPF program failed: %m"); r = bpf_firewall_compile_bpf(u, egress_name, false, &u->ip_bpf_egress, ip_allow_any, ip_deny_any); if (r < 0) - return log_unit_error_errno(u, r, "Compilation for egress BPF program failed: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Compilation of egress BPF program failed: %m"); return 0; } @@ -613,15 +613,15 @@ static int load_bpf_progs_from_fs_to_set(Unit *u, char **filter_paths, Set **set r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, NULL, &prog); if (r < 0) - return log_unit_error_errno(u, r, "Can't allocate CGROUP SKB BPF program: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Allocation of SKB BPF program failed: %m"); r = bpf_program_load_from_bpf_fs(prog, *bpf_fs_path); if (r < 0) - return log_unit_error_errno(u, r, "Loading of ingress BPF program %s failed: %m", *bpf_fs_path); + return log_unit_error_errno(u, r, "bpf-firewall: Loading of ingress BPF program %s failed: %m", *bpf_fs_path); r = set_ensure_consume(set, &bpf_program_hash_ops, TAKE_PTR(prog)); if (r < 0) - return log_unit_error_errno(u, r, "Can't add program to BPF program set: %m"); + return log_oom(); } return 0; @@ -645,7 +645,8 @@ int bpf_firewall_load_custom(Unit *u) { return supported; if (supported != BPF_FIREWALL_SUPPORTED_WITH_MULTI) - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "BPF_F_ALLOW_MULTI not supported on this manager, cannot attach custom BPF programs."); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), + "bpf-firewall: BPF_F_ALLOW_MULTI not supported, cannot attach custom BPF programs."); r = load_bpf_progs_from_fs_to_set(u, cc->ip_filters_ingress, &u->ip_bpf_custom_ingress); if (r < 0) @@ -671,7 +672,7 @@ static int attach_custom_bpf_progs(Unit *u, const char *path, int attach_type, S SET_FOREACH_MOVE(prog, *set_installed, *set) { r = bpf_program_cgroup_attach(prog, attach_type, path, BPF_F_ALLOW_MULTI); if (r < 0) - return log_unit_error_errno(u, r, "Attaching custom egress BPF program to cgroup %s failed: %m", path); + return log_unit_error_errno(u, r, "bpf-firewall: Attaching custom egress BPF program to cgroup %s failed: %m", path); } return 0; } @@ -697,16 +698,19 @@ int bpf_firewall_install(Unit *u) { if (supported < 0) return supported; if (supported == BPF_FIREWALL_UNSUPPORTED) - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "BPF firewalling not supported on this manager, proceeding without."); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), + "bpf-firewall: BPF firewalling not supported, proceeding without."); if (supported != BPF_FIREWALL_SUPPORTED_WITH_MULTI && u->type == UNIT_SLICE) - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "BPF_F_ALLOW_MULTI is not supported on this manager, not doing BPF firewall on slice units."); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), + "bpf-firewall: BPF_F_ALLOW_MULTI not supported, not doing BPF firewall on slice units."); if (supported != BPF_FIREWALL_SUPPORTED_WITH_MULTI && (!set_isempty(u->ip_bpf_custom_ingress) || !set_isempty(u->ip_bpf_custom_egress))) - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "BPF_F_ALLOW_MULTI not supported on this manager, cannot attach custom BPF programs."); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), + "bpf-firewall: BPF_F_ALLOW_MULTI not supported, cannot attach custom BPF programs."); r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL, &path); if (r < 0) - return log_unit_error_errno(u, r, "Failed to determine cgroup path: %m"); + return log_unit_error_errno(u, r, "bpf-firewall: Failed to determine cgroup path: %m"); flags = supported == BPF_FIREWALL_SUPPORTED_WITH_MULTI ? BPF_F_ALLOW_MULTI : 0; @@ -728,7 +732,8 @@ int bpf_firewall_install(Unit *u) { if (u->ip_bpf_egress) { r = bpf_program_cgroup_attach(u->ip_bpf_egress, BPF_CGROUP_INET_EGRESS, path, flags); if (r < 0) - return log_unit_error_errno(u, r, "Attaching egress BPF program to cgroup %s failed: %m", path); + return log_unit_error_errno(u, r, + "bpf-firewall: Attaching egress BPF program to cgroup %s failed: %m", path); /* Remember that this BPF program is installed now. */ u->ip_bpf_egress_installed = TAKE_PTR(u->ip_bpf_egress); @@ -737,7 +742,8 @@ int bpf_firewall_install(Unit *u) { if (u->ip_bpf_ingress) { r = bpf_program_cgroup_attach(u->ip_bpf_ingress, BPF_CGROUP_INET_INGRESS, path, flags); if (r < 0) - return log_unit_error_errno(u, r, "Attaching ingress BPF program to cgroup %s failed: %m", path); + return log_unit_error_errno(u, r, + "bpf-firewall: Attaching ingress BPF program to cgroup %s failed: %m", path); u->ip_bpf_ingress_installed = TAKE_PTR(u->ip_bpf_ingress); } @@ -824,11 +830,11 @@ int bpf_firewall_supported(void) { r = cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER); if (r < 0) - return log_error_errno(r, "Can't determine whether the unified hierarchy is used: %m"); + return log_error_errno(r, "bpf-firewall: Can't determine whether the unified hierarchy is used: %m"); if (r == 0) { bpf_firewall_unsupported_reason = log_debug_errno(SYNTHETIC_ERRNO(EUCLEAN), - "Not running with unified cgroups, BPF firewalling is not supported."); + "bpf-firewall: Not running with unified cgroup hierarchy, BPF firewalling is not supported."); return supported = BPF_FIREWALL_UNSUPPORTED; } @@ -836,21 +842,21 @@ int bpf_firewall_supported(void) { r = bpf_program_new(BPF_PROG_TYPE_CGROUP_SKB, NULL, &program); if (r < 0) { bpf_firewall_unsupported_reason = - log_debug_errno(r, "Can't allocate CGROUP SKB BPF program, BPF firewalling is not supported: %m"); + log_debug_errno(r, "bpf-firewall: Can't allocate CGROUP SKB BPF program, BPF firewalling is not supported: %m"); return supported = BPF_FIREWALL_UNSUPPORTED; } r = bpf_program_add_instructions(program, trivial, ELEMENTSOF(trivial)); if (r < 0) { bpf_firewall_unsupported_reason = - log_debug_errno(r, "Can't add trivial instructions to CGROUP SKB BPF program, BPF firewalling is not supported: %m"); + log_debug_errno(r, "bpf-firewall: Can't add trivial instructions to CGROUP SKB BPF program, BPF firewalling is not supported: %m"); return supported = BPF_FIREWALL_UNSUPPORTED; } r = bpf_program_load_kernel(program, NULL, 0); if (r < 0) { bpf_firewall_unsupported_reason = - log_debug_errno(r, "Can't load kernel CGROUP SKB BPF program, BPF firewalling is not supported: %m"); + log_debug_errno(r, "bpf-firewall: Can't load kernel CGROUP SKB BPF program, BPF firewalling is not supported: %m"); return supported = BPF_FIREWALL_UNSUPPORTED; } @@ -874,7 +880,7 @@ int bpf_firewall_supported(void) { if (bpf(BPF_PROG_DETACH, &attr, sizeof(attr)) < 0) { if (errno != EBADF) { bpf_firewall_unsupported_reason = - log_debug_errno(errno, "Didn't get EBADF from BPF_PROG_DETACH, BPF firewalling is not supported: %m"); + log_debug_errno(errno, "bpf-firewall: Didn't get EBADF from BPF_PROG_DETACH, BPF firewalling is not supported: %m"); return supported = BPF_FIREWALL_UNSUPPORTED; } @@ -882,7 +888,7 @@ int bpf_firewall_supported(void) { } else { bpf_firewall_unsupported_reason = log_debug_errno(SYNTHETIC_ERRNO(EBADE), - "Wut? Kernel accepted our invalid BPF_PROG_DETACH call? " + "bpf-firewall: Wut? Kernel accepted our invalid BPF_PROG_DETACH call? " "Something is weird, assuming BPF firewalling is broken and hence not supported."); return supported = BPF_FIREWALL_UNSUPPORTED; } @@ -902,20 +908,20 @@ int bpf_firewall_supported(void) { if (bpf(BPF_PROG_ATTACH, &attr, sizeof(attr)) < 0) { if (errno == EBADF) { - log_debug_errno(errno, "Got EBADF when using BPF_F_ALLOW_MULTI, which indicates it is supported. Yay!"); + log_debug_errno(errno, "bpf-firewall: Got EBADF when using BPF_F_ALLOW_MULTI, which indicates it is supported. Yay!"); return supported = BPF_FIREWALL_SUPPORTED_WITH_MULTI; } if (errno == EINVAL) - log_debug_errno(errno, "Got EINVAL error when using BPF_F_ALLOW_MULTI, which indicates it's not supported."); + log_debug_errno(errno, "bpf-firewall: Got EINVAL error when using BPF_F_ALLOW_MULTI, which indicates it's not supported."); else - log_debug_errno(errno, "Got unexpected error when using BPF_F_ALLOW_MULTI, assuming it's not supported: %m"); + log_debug_errno(errno, "bpf-firewall: Got unexpected error when using BPF_F_ALLOW_MULTI, assuming it's not supported: %m"); return supported = BPF_FIREWALL_SUPPORTED; } else { bpf_firewall_unsupported_reason = log_debug_errno(SYNTHETIC_ERRNO(EBADE), - "Wut? Kernel accepted our invalid BPF_PROG_ATTACH+BPF_F_ALLOW_MULTI call? " + "bpf-firewall: Wut? Kernel accepted our invalid BPF_PROG_ATTACH+BPF_F_ALLOW_MULTI call? " "Something is weird, assuming BPF firewalling is broken and hence not supported."); return supported = BPF_FIREWALL_UNSUPPORTED; } diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c index 7f50f57389..83c3bac87f 100644 --- a/src/core/bpf-foreign.c +++ b/src/core/bpf-foreign.c @@ -63,7 +63,7 @@ static int attach_programs(Unit *u, const char *path, Hashmap* foreign_by_key, u HASHMAP_FOREACH_KEY(prog, key, foreign_by_key) { r = bpf_program_cgroup_attach(prog, key->attach_type, path, attach_flags); if (r < 0) - return log_unit_error_errno(u, r, "Attaching foreign BPF program to cgroup %s failed: %m", path); + return log_unit_error_errno(u, r, "bpf-foreign: Attaching foreign BPF program to cgroup %s failed: %m", path); } return 0; @@ -89,31 +89,31 @@ static int bpf_foreign_prepare( r = path_is_fs_type(bpffs_path, BPF_FS_MAGIC); if (r < 0) return log_unit_error_errno(u, r, - "Failed to determine filesystem type of %s: %m", bpffs_path); + "bpf-foreign: Failed to determine filesystem type of %s: %m", bpffs_path); if (r == 0) return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL), - "Path in BPF filesystem is expected."); + "bpf-foreign: Path in BPF filesystem is expected."); r = bpf_program_new_from_bpffs_path(bpffs_path, &prog); if (r < 0) - return log_unit_error_errno(u, r, "Failed to create foreign BPFProgram: %m"); + return log_unit_error_errno(u, r, "bpf-foreign: Failed to create foreign BPF program: %m"); r = bpf_program_get_id_by_fd(prog->kernel_fd, &prog_id); if (r < 0) - return log_unit_error_errno(u, r, "Failed to get BPF program id by fd: %m"); + return log_unit_error_errno(u, r, "bpf-foreign: Failed to get BPF program id from fd: %m"); r = bpf_foreign_key_new(prog_id, attach_type, &key); if (r < 0) return log_unit_error_errno(u, r, - "Failed to create foreign BPF program key from path '%s': %m", bpffs_path); + "bpf-foreign: Failed to create foreign BPF program key from path '%s': %m", bpffs_path); r = hashmap_ensure_put(&u->bpf_foreign_by_key, &bpf_foreign_by_key_hash_ops, key, prog); if (r == -EEXIST) { - log_unit_warning_errno(u, r, "Foreign BPF program already exists, ignoring: %m"); + log_unit_warning_errno(u, r, "bpf-foreign: Foreign BPF program already exists, ignoring: %m"); return 0; } if (r < 0) - return log_unit_error_errno(u, r, "Failed to put foreign BPFProgram into map: %m"); + return log_unit_error_errno(u, r, "bpf-foreign: Failed to put foreign BPF program into map: %m"); TAKE_PTR(key); TAKE_PTR(prog); @@ -134,17 +134,17 @@ int bpf_foreign_install(Unit *u) { r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL, &cgroup_path); if (r < 0) - return log_unit_error_errno(u, r, "Failed to get cgroup path: %m"); + return log_unit_error_errno(u, r, "bpf-foreign: Failed to get cgroup path: %m"); LIST_FOREACH(programs, p, cc->bpf_foreign_programs) { r = bpf_foreign_prepare(u, p->attach_type, p->bpffs_path); if (r < 0) - return log_unit_error_errno(u, r, "Failed to prepare foreign BPF hashmap: %m"); + return log_unit_error_errno(u, r, "bpf-foreign: Failed to prepare foreign BPF hashmap: %m"); } r = attach_programs(u, cgroup_path, u->bpf_foreign_by_key, BPF_F_ALLOW_MULTI); if (r < 0) - return log_unit_error_errno(u, r, "Failed to install foreign BPF programs: %m"); + return log_unit_error_errno(u, r, "bpf-foreign: Failed to install foreign BPF programs: %m"); return 0; } diff --git a/src/core/bpf-lsm.c b/src/core/bpf-lsm.c index 3ebc2fd166..f3b9339558 100644 --- a/src/core/bpf-lsm.c +++ b/src/core/bpf-lsm.c @@ -62,29 +62,29 @@ static int prepare_restrict_fs_bpf(struct restrict_fs_bpf **ret_obj) { obj = restrict_fs_bpf__open(); if (!obj) - return log_error_errno(errno, "Failed to open BPF object: %m"); + return log_error_errno(errno, "bpf-lsm: Failed to open BPF object: %m"); /* TODO Maybe choose a number based on runtime information? */ r = sym_bpf_map__resize(obj->maps.cgroup_hash, CGROUP_HASH_SIZE_MAX); assert(r <= 0); if (r < 0) - return log_error_errno(r, "Failed to resize BPF map '%s': %m", + return log_error_errno(r, "bpf-lsm: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.cgroup_hash)); /* Dummy map to satisfy the verifier */ inner_map_fd = sym_bpf_create_map(BPF_MAP_TYPE_HASH, sizeof(uint32_t), sizeof(uint32_t), 128, 0); if (inner_map_fd < 0) - return log_error_errno(errno, "Failed to create BPF map: %m"); + return log_error_errno(errno, "bpf-lsm: Failed to create BPF map: %m"); r = sym_bpf_map__set_inner_map_fd(obj->maps.cgroup_hash, inner_map_fd); assert(r <= 0); if (r < 0) - return log_error_errno(r, "Failed to set inner map fd: %m"); + return log_error_errno(r, "bpf-lsm: Failed to set inner map fd: %m"); r = restrict_fs_bpf__load(obj); assert(r <= 0); if (r < 0) - return log_error_errno(r, "Failed to load BPF object: %m"); + return log_error_errno(r, "bpf-lsm: Failed to load BPF object: %m"); *ret_obj = TAKE_PTR(obj); @@ -104,7 +104,7 @@ static int mac_bpf_use(void) { r = read_one_line_file("/sys/kernel/security/lsm", &lsm_list); if (r < 0) { if (r != -ENOENT) - log_notice_errno(r, "Failed to read /sys/kernel/security/lsm, assuming bpf is unavailable: %m"); + log_notice_errno(r, "bpf-lsm: Failed to read /sys/kernel/security/lsm, assuming bpf is unavailable: %m"); return 0; } @@ -117,7 +117,7 @@ static int mac_bpf_use(void) { if (r == -ENOMEM) return log_oom(); if (r < 0) { - log_notice_errno(r, "Failed to parse /sys/kernel/security/lsm, assuming bpf is unavailable: %m"); + log_notice_errno(r, "bpf-lsm: Failed to parse /sys/kernel/security/lsm, assuming bpf is unavailable: %m"); return 0; } @@ -141,13 +141,13 @@ bool lsm_bpf_supported(bool initialize) { r = mac_bpf_use(); if (r < 0) { - log_warning_errno(r, "Can't determine whether the BPF LSM module is used: %m"); + log_warning_errno(r, "bpf-lsm: Can't determine whether the BPF LSM module is used: %m"); return (supported = false); } if (r == 0) { log_info_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "BPF LSM hook not enabled in the kernel, LSM BPF not supported"); + "bpf-lsm: BPF LSM hook not enabled in the kernel, BPF LSM not supported"); return (supported = false); } @@ -157,7 +157,7 @@ bool lsm_bpf_supported(bool initialize) { if (!bpf_can_link_lsm_program(obj->progs.restrict_filesystems)) { log_warning_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "Failed to link BPF program. Assuming BPF is not available"); + "bpf-lsm: Failed to link program; assuming BPF LSM is not available"); return (supported = false); } @@ -178,10 +178,10 @@ int lsm_bpf_setup(Manager *m) { link = sym_bpf_program__attach_lsm(obj->progs.restrict_filesystems); r = sym_libbpf_get_error(link); if (r != 0) - return log_error_errno(r, "Failed to link '%s' LSM BPF program: %m", + return log_error_errno(r, "bpf-lsm: Failed to link '%s' LSM BPF program: %m", sym_bpf_program__name(obj->progs.restrict_filesystems)); - log_info("LSM BPF program attached"); + log_info("bpf-lsm: LSM BPF program attached"); obj->links.restrict_filesystems = TAKE_PTR(link); m->restrict_fs = TAKE_PTR(obj); @@ -200,7 +200,7 @@ int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, bool allo if (!u->manager->restrict_fs) return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL), - "Restrict filesystems BPF object is not set, BPF LSM setup has failed?"); + "bpf-lsm: BPF LSM object is not installed, has setup failed?"); int inner_map_fd = sym_bpf_create_map( BPF_MAP_TYPE_HASH, @@ -209,39 +209,39 @@ int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, bool allo 128, /* Should be enough for all filesystem types */ 0); if (inner_map_fd < 0) - return log_unit_error_errno(u, errno, "Failed to create inner LSM map: %m"); + return log_unit_error_errno(u, errno, "bpf-lsm: Failed to create inner BPF map: %m"); int outer_map_fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash); if (outer_map_fd < 0) - return log_unit_error_errno(u, errno, "Failed to get BPF map fd: %m"); + return log_unit_error_errno(u, errno, "bpf-lsm: Failed to get BPF map fd: %m"); if (sym_bpf_map_update_elem(outer_map_fd, &u->cgroup_id, &inner_map_fd, BPF_ANY) != 0) - return log_unit_error_errno(u, errno, "Error populating LSM BPF map: %m"); + return log_unit_error_errno(u, errno, "bpf-lsm: Error populating BPF map: %m"); uint32_t allow = allow_list; /* Use key 0 to store whether this is an allow list or a deny list */ if (sym_bpf_map_update_elem(inner_map_fd, &zero, &allow, BPF_ANY) != 0) - return log_unit_error_errno(u, errno, "Error initializing BPF map: %m"); + return log_unit_error_errno(u, errno, "bpf-lsm: Error initializing map: %m"); SET_FOREACH(fs, filesystems) { r = fs_type_from_string(fs, &magic); if (r < 0) { - log_unit_warning(u, "Invalid filesystem name '%s', ignoring.", fs); + log_unit_warning(u, "bpf-lsm: Invalid filesystem name '%s', ignoring.", fs); continue; } - log_unit_debug(u, "Restricting filesystem access to '%s'", fs); + log_unit_debug(u, "bpf-lsm: Restricting filesystem access to '%s'", fs); for (int i = 0; i < FILESYSTEM_MAGIC_MAX; i++) { if (magic[i] == 0) break; if (sym_bpf_map_update_elem(inner_map_fd, &magic[i], &dummy_value, BPF_ANY) != 0) { - r = log_unit_error_errno(u, errno, "Failed to update BPF map: %m"); + r = log_unit_error_errno(u, errno, "bpf-lsm: Failed to update BPF map: %m"); if (sym_bpf_map_delete_elem(outer_map_fd, &u->cgroup_id) != 0) - log_unit_debug_errno(u, errno, "Failed to delete cgroup entry from LSM BPF map: %m"); + log_unit_debug_errno(u, errno, "bpf-lsm: Failed to delete cgroup entry from BPF map: %m"); return r; } @@ -264,10 +264,10 @@ int lsm_bpf_cleanup(const Unit *u) { int fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash); if (fd < 0) - return log_unit_error_errno(u, errno, "Failed to get BPF map fd: %m"); + return log_unit_error_errno(u, errno, "bpf-lsm: Failed to get BPF map fd: %m"); if (sym_bpf_map_delete_elem(fd, &u->cgroup_id) != 0) - return log_unit_debug_errno(u, errno, "Failed to delete cgroup entry from LSM BPF map: %m"); + return log_unit_debug_errno(u, errno, "bpf-lsm: Failed to delete cgroup entry from LSM BPF map: %m"); return 0; } @@ -291,11 +291,11 @@ bool lsm_bpf_supported(bool initialize) { } int lsm_bpf_setup(Manager *m) { - return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to set up LSM BPF: %m"); + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "bpf-lsm: Failed to set up LSM BPF: %m"); } int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, const bool allow_list) { - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to restrict filesystems using LSM BPF: %m"); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "bpf-lsm: Failed to restrict filesystems using LSM BPF: %m"); } int lsm_bpf_cleanup(const Unit *u) { @@ -330,7 +330,7 @@ int lsm_bpf_parse_filesystem( set = filesystem_set_find(name); if (!set) { log_syntax(unit, flags & FILESYSTEM_PARSE_LOG ? LOG_WARNING : LOG_DEBUG, filename, line, 0, - "Unknown filesystem group, ignoring: %s", name); + "bpf-lsm: Unknown filesystem group, ignoring: %s", name); return 0; } diff --git a/src/core/bpf-socket-bind.c b/src/core/bpf-socket-bind.c index 2000c5029b..3aa1bfa1f1 100644 --- a/src/core/bpf-socket-bind.c +++ b/src/core/bpf-socket-bind.c @@ -69,27 +69,27 @@ static int prepare_socket_bind_bpf( if (allow_count > SOCKET_BIND_MAX_RULES) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL), - "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES); + "bpf-socket-bind: Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES); if (deny_count > SOCKET_BIND_MAX_RULES) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, SYNTHETIC_ERRNO(EINVAL), - "Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES); + "bpf-socket-bind: Maximum number of socket bind rules=%u is exceeded", SOCKET_BIND_MAX_RULES); obj = socket_bind_bpf__open(); if (!obj) - return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, "Failed to open BPF object: %m"); + return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, "bpf-socket-bind: Failed to open BPF object: %m"); if (sym_bpf_map__resize(obj->maps.sd_bind_allow, MAX(allow_count, 1u)) != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno, - "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow)); + "bpf-socket-bind: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_allow)); if (sym_bpf_map__resize(obj->maps.sd_bind_deny, MAX(deny_count, 1u)) != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno, - "Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny)); + "bpf-socket-bind: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_bind_deny)); if (socket_bind_bpf__load(obj) != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, - "Failed to load BPF object: %m"); + "bpf-socket-bind: Failed to load BPF object: %m"); allow_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_allow); assert(allow_map_fd >= 0); @@ -97,7 +97,7 @@ static int prepare_socket_bind_bpf( r = update_rules_map(allow_map_fd, allow); if (r < 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r, - "Failed to put socket bind allow rules into BPF map '%s'", + "bpf-socket-bind: Failed to put socket bind allow rules into BPF map '%s'", sym_bpf_map__name(obj->maps.sd_bind_allow)); deny_map_fd = sym_bpf_map__fd(obj->maps.sd_bind_deny); @@ -106,7 +106,7 @@ static int prepare_socket_bind_bpf( r = update_rules_map(deny_map_fd, deny); if (r < 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r, - "Failed to put socket bind deny rules into BPF map '%s'", + "bpf-socket-bind: Failed to put socket bind deny rules into BPF map '%s'", sym_bpf_map__name(obj->maps.sd_bind_deny)); *ret_obj = TAKE_PTR(obj); @@ -121,13 +121,13 @@ int bpf_socket_bind_supported(void) { return false; if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SOCK_ADDR, /*ifindex=*/0)) { - log_debug("BPF program type cgroup_sock_addr is not supported"); + log_debug("bpf-socket-bind: BPF program type cgroup_sock_addr is not supported"); return false; } r = prepare_socket_bind_bpf(/*unit=*/NULL, /*allow_rules=*/NULL, /*deny_rules=*/NULL, &obj); if (r < 0) { - log_debug_errno(r, "BPF based socket_bind is not supported: %m"); + log_debug_errno(r, "bpf-socket-bind: socket bind filtering is not supported: %m"); return false; } @@ -147,7 +147,7 @@ int bpf_socket_bind_add_initial_link_fd(Unit *u, int fd) { r = fdset_put(u->initial_socket_bind_link_fds, fd); if (r < 0) - return log_unit_error_errno(u, r, "Failed to put socket-bind BPF link fd %d to initial fdset", fd); + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to put BPF fd %d to initial fdset", fd); return 0; } @@ -168,29 +168,29 @@ static int socket_bind_install_impl(Unit *u) { r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL, &cgroup_path); if (r < 0) - return log_unit_error_errno(u, r, "Failed to get cgroup path: %m"); + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to get cgroup path: %m"); if (!cc->socket_bind_allow && !cc->socket_bind_deny) return 0; r = prepare_socket_bind_bpf(u, cc->socket_bind_allow, cc->socket_bind_deny, &obj); if (r < 0) - return log_unit_error_errno(u, r, "Failed to load BPF object: %m"); + return log_unit_error_errno(u, r, "bpf-socket-bind: Failed to load BPF object: %m"); cgroup_fd = open(cgroup_path, O_RDONLY | O_CLOEXEC, 0); if (cgroup_fd < 0) - return log_unit_error_errno(u, errno, "Failed to open cgroup=%s for reading: %m", cgroup_path); + 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); if (r != 0) - return log_unit_error_errno(u, r, "Failed to link '%s' cgroup-bpf program: %m", + 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); if (r != 0) - return log_unit_error_errno(u, r, "Failed to link '%s' cgroup-bpf program: %m", + 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)); u->ipv4_socket_bind_link = TAKE_PTR(ipv4); @@ -234,7 +234,8 @@ int bpf_socket_bind_add_initial_link_fd(Unit *u, int fd) { } int bpf_socket_bind_install(Unit *u) { - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to install socket bind: BPF framework is not supported"); + return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), + "bpf-socket-bind: Failed to install; BPF framework is not supported"); } int bpf_serialize_socket_bind(Unit *u, FILE *f, FDSet *fds) { diff --git a/src/core/restrict-ifaces.c b/src/core/restrict-ifaces.c index a3d9985418..a0ecaff814 100644 --- a/src/core/restrict-ifaces.c +++ b/src/core/restrict-ifaces.c @@ -34,19 +34,19 @@ static int prepare_restrict_ifaces_bpf( obj = restrict_ifaces_bpf__open(); if (!obj) - return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, "Failed to open BPF object: %m"); + return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, errno, "restrict-interfaces: Failed to open BPF object: %m"); r = sym_bpf_map__resize(obj->maps.sd_restrictif, MAX(set_size(restrict_network_interfaces), 1u)); if (r != 0) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, r, - "Failed to resize BPF map '%s': %m", + "restrict-interfaces: Failed to resize BPF map '%s': %m", sym_bpf_map__name(obj->maps.sd_restrictif)); obj->rodata->is_allow_list = is_allow_list; r = restrict_ifaces_bpf__load(obj); if (r != 0) - return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, r, "Failed to load BPF object: %m"); + return log_unit_full_errno(u, u ? LOG_ERR : LOG_DEBUG, r, "restrict-interfaces: Failed to load BPF object: %m"); map_fd = sym_bpf_map__fd(obj->maps.sd_restrictif); @@ -56,13 +56,15 @@ static int prepare_restrict_ifaces_bpf( ifindex = rtnl_resolve_interface(&rtnl, iface); if (ifindex < 0) { - log_unit_warning_errno(u, ifindex, "Couldn't find index of network interface '%s', ignoring: %m", iface); + log_unit_warning_errno(u, ifindex, + "restrict-interfaces: Couldn't find index of network interface '%s', ignoring: %m", + iface); continue; } if (sym_bpf_map_update_elem(map_fd, &ifindex, &dummy, BPF_ANY)) return log_unit_full_errno(u, u ? LOG_ERR : LOG_WARNING, errno, - "Failed to update BPF map '%s' fd: %m", + "restrict-interfaces: Failed to update BPF map '%s' fd: %m", sym_bpf_map__name(obj->maps.sd_restrictif)); } @@ -82,13 +84,13 @@ int restrict_network_interfaces_supported(void) { return (supported = false); if (!sym_bpf_probe_prog_type(BPF_PROG_TYPE_CGROUP_SKB, /*ifindex=*/0)) { - log_debug("BPF program type cgroup_skb is not supported"); + log_debug("restrict-interfaces: BPF program type cgroup_skb is not supported"); return (supported = false); } r = prepare_restrict_ifaces_bpf(NULL, true, NULL, &obj); if (r < 0) { - log_debug_errno(r, "Failed to load BPF object: %m"); + log_debug_errno(r, "restrict-interfaces: Failed to load BPF object: %m"); return (supported = false); } @@ -109,7 +111,7 @@ static int restrict_network_interfaces_install_impl(Unit *u) { r = cg_get_path(SYSTEMD_CGROUP_CONTROLLER, u->cgroup_path, NULL, &cgroup_path); if (r < 0) - return log_unit_error_errno(u, r, "Failed to get cgroup path: %m"); + return log_unit_error_errno(u, r, "restrict-interfaces: Failed to get cgroup path: %m"); if (!cc->restrict_network_interfaces) return 0; @@ -128,12 +130,12 @@ static int restrict_network_interfaces_install_impl(Unit *u) { ingress_link = sym_bpf_program__attach_cgroup(obj->progs.sd_restrictif_i, cgroup_fd); r = sym_libbpf_get_error(ingress_link); if (r != 0) - return log_unit_error_errno(u, r, "Failed to create ingress cgroup link: %m"); + 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); if (r != 0) - return log_unit_error_errno(u, r, "Failed to create egress cgroup link: %m"); + return log_unit_error_errno(u, r, "restrict-interfaces: Failed to create egress cgroup link: %m"); u->restrict_ifaces_ingress_bpf_link = TAKE_PTR(ingress_link); u->restrict_ifaces_egress_bpf_link = TAKE_PTR(egress_link); @@ -172,7 +174,8 @@ int restrict_network_interfaces_add_initial_link_fd(Unit *u, int fd) { r = fdset_put(u->initial_restric_ifaces_link_fds, fd); if (r < 0) - return log_unit_error_errno(u, r, "Failed to put restrict-ifaces-bpf-fd %d to restored fdset: %m", fd); + return log_unit_error_errno(u, r, + "restrict-interfaces: Failed to put restrict-ifaces-bpf-fd %d to restored fdset: %m", fd); return 0; } @@ -184,7 +187,7 @@ int restrict_network_interfaces_supported(void) { int restrict_network_interfaces_install(Unit *u) { return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), - "Failed to install RestrictInterfaces: BPF programs built from source code are not supported: %m"); + "restrict-interfaces: Failed to install; BPF programs built from source code are not supported: %m"); } int serialize_restrict_network_interfaces(Unit *u, FILE *f, FDSet *fds) {