core: Don't leak BPF links when realizing a cgroup again

cgroup_context_apply() attaches the BPF programs again whenever the
cgroup is realised again, for example, if someone does set-property or
daemon-relaod.

As it is now, their installers overwrite the links of the previous
installation without freeing them, so the previous programs stay
attached until the cgroup is removed, and keep enforcing whatever
settings they were loaded with.

For example, a unit with SocketBindDeny=any that is allowed to bind to a
port with "systemctl set-property foo.service SocketBindAllow=tcp:1234"
still cannot do so once its cgroup is realised again, as the previous
program keeps denying it. Whoops!

To fix this let's free the previous links once the new ones are
attached.

(cherry picked from commit 2f11fb19b7292339632e9b396fcab12729cde1ff)
This commit is contained in:
Chris Down
2026-10-16 17:24:50 +01:00
committed by Luca Boccassi
parent 356b2edcc1
commit 8ac16654bc
3 changed files with 5 additions and 5 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ static int bind_network_interface_install_impl(Unit *u, CGroupRuntime *crt) {
return log_unit_error_errno(u, r, "bind-interface: Failed to create cgroup link: %m");
/* Store the link in CGroupRuntime */
crt->bpf_bind_network_interface_link = TAKE_PTR(link);
free_and_replace_full(crt->bpf_bind_network_interface_link, link, bpf_link_free);
log_unit_debug(u, "bind-interface: Successfully installed VRF binding for interface '%s' (ifindex=%d)",
cc->bind_network_interface, ifindex);
+2 -2
View File
@@ -138,8 +138,8 @@ static int restrict_ifaces_install_impl(Unit *u, CGroupRuntime *crt) {
if (r != 0)
return log_unit_error_errno(u, r, "restrict-interfaces: Failed to create egress cgroup link: %m");
crt->restrict_ifaces_ingress_bpf_link = TAKE_PTR(ingress_link);
crt->restrict_ifaces_egress_bpf_link = TAKE_PTR(egress_link);
free_and_replace_full(crt->restrict_ifaces_ingress_bpf_link, ingress_link, bpf_link_free);
free_and_replace_full(crt->restrict_ifaces_egress_bpf_link, egress_link, bpf_link_free);
return 0;
}
+2 -2
View File
@@ -206,8 +206,8 @@ static int socket_bind_install_impl(Unit *u) {
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));
crt->ipv4_socket_bind_link = TAKE_PTR(ipv4);
crt->ipv6_socket_bind_link = TAKE_PTR(ipv6);
free_and_replace_full(crt->ipv4_socket_bind_link, ipv4, bpf_link_free);
free_and_replace_full(crt->ipv6_socket_bind_link, ipv6, bpf_link_free);
return 0;
}