From 084d0849fc864b0377551b211def7a89b642c5e9 Mon Sep 17 00:00:00 2001 From: Julia Kartseva Date: Thu, 4 Nov 2021 18:52:02 -0700 Subject: [PATCH 1/2] core: fix bpf-foreign cg controller realization Requiring /sys/fs/bpf path to be a mount point at the moment of cgroup controllers realization does more harm than good, because: * Realization happens early on boot, the mount point may not be ready at the time. That happens if mounts are made by a .mount unit (the issue we encountered). * BPF filesystem may be mounted on another point. Remove the check. Instead verify that path provided by BPFProgram= is within BPF fs when unit properties are parsed. Split in two commits for simple backport. --- src/core/bpf-foreign.c | 10 ---------- src/core/bpf-foreign.h | 5 ++++- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c index 6b93b9785fb5..686c14ce1f18 100644 --- a/src/core/bpf-foreign.c +++ b/src/core/bpf-foreign.c @@ -111,16 +111,6 @@ static int bpf_foreign_prepare( return 0; } -int bpf_foreign_supported(void) { - int r; - - r = cg_all_unified(); - if (r <= 0) - return r; - - return path_is_mount_point("/sys/fs/bpf", NULL, 0); -} - int bpf_foreign_install(Unit *u) { _cleanup_free_ char *cgroup_path = NULL; CGroupBPFForeignProgram *p; diff --git a/src/core/bpf-foreign.h b/src/core/bpf-foreign.h index 9559cd79812b..e387b1b1d389 100644 --- a/src/core/bpf-foreign.h +++ b/src/core/bpf-foreign.h @@ -4,7 +4,10 @@ #include "unit.h" -int bpf_foreign_supported(void); +static inline int bpf_foreign_supported(void) { + return cg_all_unified(); +} + /* * Attach cgroup-bpf programs foreign to systemd, i.e. loaded to the kernel by an entity * external to systemd. From dedca960afdee5797d19929c43853513711e3e3d Mon Sep 17 00:00:00 2001 From: Julia Kartseva Date: Thu, 4 Nov 2021 18:55:55 -0700 Subject: [PATCH 2/2] core: check fs type of BPFProgram= property path Tests: ``` % stat --file-system --format="%T" /root/bpf/trivial/ bpf_fs % systemd-nspawn -D/ --volatile=yes \ --property=BPFProgram=egress:/root/bpf/trivial/cgroup_skb_egress \ --quiet -- ping -c 5 -W 1 ::1 PING ::1(::1) 56 data bytes --- ::1 ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4110ms ``` ``` % stat --file-system --format='%T' /root/meh btrfs % systemd-nspawn -D/ --volatile=yes --property=BPFProgram=egress:/root/meh --quiet -- ping -c 5 -W 1 ::1 ``` sudo ./build/systemd-nspawn \ -D/ --volatile=yes --property=BPFProgram=egress:/home/hex --quiet -- \ ping -c 1 -W 1 ::1 PING ::1(::1) 56 data bytes 64 bytes from ::1: icmp_seq=1 ttl=64 time=0.017 ms --- ::1 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms --- src/core/bpf-foreign.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/core/bpf-foreign.c b/src/core/bpf-foreign.c index 686c14ce1f18..8538792b60db 100644 --- a/src/core/bpf-foreign.c +++ b/src/core/bpf-foreign.c @@ -4,8 +4,10 @@ #include "bpf-program.h" #include "cgroup.h" #include "memory-util.h" +#include "missing_magic.h" #include "mountpoint-util.h" #include "set.h" +#include "stat-util.h" typedef struct BPFForeignKey BPFForeignKey; struct BPFForeignKey { @@ -84,6 +86,14 @@ static int bpf_foreign_prepare( assert(u); assert(bpffs_path); + 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); + if (r == 0) + return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL), + "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");