Merge pull request #23596 from keszybz/bpf-messages-more
Silence messages from libbpf
This commit is contained in:
+35
-29
@@ -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;
|
||||
}
|
||||
|
||||
+11
-11
@@ -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;
|
||||
}
|
||||
|
||||
+28
-42
@@ -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
|
||||
@@ -61,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");
|
||||
return log_error_errno(r, "bpf-lsm: Failed to load BPF object: %m");
|
||||
|
||||
*ret_obj = TAKE_PTR(obj);
|
||||
|
||||
@@ -103,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;
|
||||
}
|
||||
|
||||
@@ -116,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;
|
||||
}
|
||||
|
||||
@@ -135,33 +136,18 @@ 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -171,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);
|
||||
}
|
||||
|
||||
@@ -192,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);
|
||||
@@ -214,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,
|
||||
@@ -223,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;
|
||||
}
|
||||
@@ -278,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;
|
||||
}
|
||||
@@ -305,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) {
|
||||
@@ -344,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;
|
||||
}
|
||||
|
||||
|
||||
+21
-27
@@ -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 */
|
||||
@@ -68,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);
|
||||
@@ -96,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);
|
||||
@@ -105,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);
|
||||
@@ -116,25 +117,17 @@ 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)) {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -154,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;
|
||||
}
|
||||
@@ -175,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);
|
||||
@@ -241,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) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
bool cgroup_bpf_supported(void);
|
||||
+141
-134
@@ -1,139 +1,146 @@
|
||||
# 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',
|
||||
)
|
||||
|
||||
if conf.get('BPF_FRAMEWORK') == 1
|
||||
libcore_sources += files(
|
||||
'bpf-util.c',
|
||||
'bpf-util.h',
|
||||
)
|
||||
endif
|
||||
|
||||
subdir('bpf')
|
||||
|
||||
|
||||
+21
-26
@@ -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) {
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
@@ -78,29 +80,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;
|
||||
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");
|
||||
return supported = 0;
|
||||
log_debug_errno(r, "restrict-interfaces: Failed to load BPF object: %m");
|
||||
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) {
|
||||
@@ -117,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;
|
||||
@@ -136,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);
|
||||
@@ -180,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;
|
||||
}
|
||||
@@ -192,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) {
|
||||
|
||||
+26
-2
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -108,10 +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");
|
||||
|
||||
if (getuid() != 0)
|
||||
return log_tests_skipped("not running as root");
|
||||
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);
|
||||
@@ -125,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)
|
||||
|
||||
@@ -553,10 +553,10 @@ 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.");
|
||||
return log_error_errno(errno, "Failed to kill our own parent: %m");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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]);
|
||||
|
||||
Reference in New Issue
Block a user