Skip to content

Commit 248e00a

Browse files
lmbAlexei Starovoitov
authored andcommitted
bpf: cgroup: Allow multi-attach program to replace itself
When using BPF_PROG_ATTACH to attach a program to a cgroup in BPF_F_ALLOW_MULTI mode, it is not possible to replace a program with itself. This is because the check for duplicate programs doesn't take the replacement program into account. Replacing a program with itself might seem weird, but it has some uses: first, it allows resetting the associated cgroup storage. Second, it makes the API consistent with the non-ALLOW_MULTI usage, where it is possible to replace a program with itself. Third, it aligns BPF_PROG_ATTACH with bpf_link, where replacing itself is also supported. Sice this code has been refactored a few times this change will only apply to v5.7 and later. Adjustments could be made to commit 1020c1f ("bpf: Simplify __cgroup_bpf_attach") and commit d7bf2c1 ("bpf: allocate cgroup storage entries on attaching bpf programs") as well as commit 324bda9 ("bpf: multi program support for cgroup+bpf") Fixes: af6eea5 ("bpf: Implement bpf_link-based cgroup BPF program attachment") Signed-off-by: Lorenz Bauer <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]> Link: https://lore.kernel.org/bpf/[email protected]
1 parent 26afa0a commit 248e00a

File tree

2 files changed

+8
-1
lines changed

2 files changed

+8
-1
lines changed

kernel/bpf/cgroup.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ static struct bpf_prog_list *find_attach_entry(struct list_head *progs,
378378
}
379379

380380
list_for_each_entry(pl, progs, node) {
381-
if (prog && pl->prog == prog)
381+
if (prog && pl->prog == prog && prog != replace_prog)
382382
/* disallow attaching the same prog twice */
383383
return ERR_PTR(-EINVAL);
384384
if (link && pl->link == link)

tools/testing/selftests/bpf/prog_tests/cgroup_attach_multi.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ void test_cgroup_attach_multi(void)
230230
"prog_replace", "errno=%d\n", errno))
231231
goto err;
232232

233+
/* replace program with itself */
234+
attach_opts.replace_prog_fd = allow_prog[6];
235+
if (CHECK(bpf_prog_attach_xattr(allow_prog[6], cg1,
236+
BPF_CGROUP_INET_EGRESS, &attach_opts),
237+
"prog_replace", "errno=%d\n", errno))
238+
goto err;
239+
233240
value = 0;
234241
CHECK_FAIL(bpf_map_update_elem(map_fd, &key, &value, 0));
235242
CHECK_FAIL(system(PING_CMD));

0 commit comments

Comments
 (0)