From: Mike Yuan Date: Wed, 24 Dec 2025 19:16:51 +0000 (+0100) Subject: core/cgroup: fix potential bpf link fd leak during deserialization X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e78f61576322785b96994a5676ec5774f2c13e6a;p=thirdparty%2Fsystemd.git core/cgroup: fix potential bpf link fd leak during deserialization Also add a comment explaining the deserialization mechanism, as requested in https://github.com/systemd/systemd/pull/40202#discussion_r2649274628 --- diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 6e6d6068544..3e37f0444d5 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -4459,34 +4459,24 @@ int cgroup_runtime_deserialize_one(Unit *u, const char *key, const char *value, if (MATCH_DESERIALIZE_IMMEDIATE(u, "cgroup-invalidated-mask", key, value, cg_mask_from_string, cgroup_invalidated_mask)) return 1; - if (STR_IN_SET(key, "ipv4-socket-bind-bpf-link-fd", "ipv6-socket-bind-bpf-link-fd")) { - int fd; - - fd = deserialize_fd(fds, value); - if (fd >= 0) - (void) bpf_socket_bind_add_initial_link_fd(u, fd); - - return 1; - } - if (STR_IN_SET(key, - "ip-bpf-ingress-installed", "ip-bpf-egress-installed", "bpf-device-control-installed", + "ip-bpf-ingress-installed", "ip-bpf-egress-installed", "ip-bpf-custom-ingress-installed", "ip-bpf-custom-egress-installed")) { CGroupRuntime *crt = unit_setup_cgroup_runtime(u); if (!crt) log_oom_debug(); else { + if (streq(key, "bpf-device-control-installed")) + (void) bpf_program_deserialize_attachment(value, fds, &crt->bpf_device_control_installed); + if (streq(key, "ip-bpf-ingress-installed")) (void) bpf_program_deserialize_attachment(value, fds, &crt->ip_bpf_ingress_installed); if (streq(key, "ip-bpf-egress-installed")) (void) bpf_program_deserialize_attachment(value, fds, &crt->ip_bpf_egress_installed); - if (streq(key, "bpf-device-control-installed")) - (void) bpf_program_deserialize_attachment(value, fds, &crt->bpf_device_control_installed); - if (streq(key, "ip-bpf-custom-ingress-installed")) (void) bpf_program_deserialize_attachment_set(value, fds, &crt->ip_bpf_custom_ingress_installed); @@ -4497,12 +4487,32 @@ int cgroup_runtime_deserialize_one(Unit *u, const char *key, const char *value, return 1; } + /* We keep the previous bpf link fds stashed until we reattach anew, to close the window where + * the cgroup restrictions would otherwise be lifted. */ + + if (STR_IN_SET(key, "ipv4-socket-bind-bpf-link-fd", "ipv6-socket-bind-bpf-link-fd")) { + _cleanup_close_ int fd = -EBADF; + + fd = deserialize_fd(fds, value); + if (fd >= 0) { + r = bpf_socket_bind_add_initial_link_fd(u, fd); + if (r >= 0) + TAKE_FD(fd); + } + + return 1; + } + if (streq(key, "restrict-ifaces-bpf-fd")) { - int fd; + _cleanup_close_ int fd = -EBADF; fd = deserialize_fd(fds, value); - if (fd >= 0) - (void) bpf_restrict_ifaces_add_initial_link_fd(u, fd); + if (fd >= 0) { + r = bpf_restrict_ifaces_add_initial_link_fd(u, fd); + if (r >= 0) + TAKE_FD(fd); + } + return 1; }