There are two bpf_link__destroy(freplace_link) calls in test_tailcall_bpf2bpf_freplace(). After the first bpf_link__destroy() is called, if the following bpf_map_{update,delete}_elem() throws an exception, it will jump to the "out" label and call bpf_link__destroy() again, causing double free and eventually leading to a segfault. Fix this issue by moving bpf_link__destroy() out of the "out" label and only calling it when freplace_link exists and has not been freed. Fixes: 021611d33e78 ("selftests/bpf: Add test to verify tailcall and freplace restrictions") Signed-off-by: Tengda Wu <wutengda@xxxxxxxxxxxxxxx> --- tools/testing/selftests/bpf/prog_tests/tailcalls.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/bpf/prog_tests/tailcalls.c b/tools/testing/selftests/bpf/prog_tests/tailcalls.c index 544144620ca6..028439dd2c5f 100644 --- a/tools/testing/selftests/bpf/prog_tests/tailcalls.c +++ b/tools/testing/selftests/bpf/prog_tests/tailcalls.c @@ -1624,7 +1624,7 @@ static void test_tailcall_bpf2bpf_freplace(void) freplace_link = bpf_program__attach_freplace(freplace_skel->progs.entry_freplace, prog_fd, "subprog_tc"); if (!ASSERT_ERR_PTR(freplace_link, "attach_freplace failure")) - goto out; + goto out_free_link; err = bpf_map_delete_elem(map_fd, &key); if (!ASSERT_OK(err, "delete_elem from jmp_table")) @@ -1638,11 +1638,11 @@ static void test_tailcall_bpf2bpf_freplace(void) goto out; err = bpf_map_update_elem(map_fd, &key, &prog_fd, BPF_ANY); - if (!ASSERT_ERR(err, "update jmp_table failure")) - goto out; + ASSERT_ERR(err, "update jmp_table failure"); -out: +out_free_link: bpf_link__destroy(freplace_link); +out: tailcall_freplace__destroy(freplace_skel); tc_bpf2bpf__destroy(tc_skel); } -- 2.34.1