Skip to content

Commit

Permalink
selftests/bpf: Fix multiple segfaults in bpf_tcp_ca
Browse files Browse the repository at this point in the history
Several test cases create a bpf_link from a struct_ops but attempt to use
it without first error-checking. This results is segfaults if the arch does
not yet support BPF struct_ops (e.g. mips64el):

    # ./test_progs -n 29/9
    test_update_ca:PASS:open 0 nsec
    test_update_ca:FAIL:attach_struct_ops unexpected error: -524
    do_test:PASS:socket 0 nsec
    do_test:PASS:socket 0 nsec
    settcpca:FAIL:setsockopt unexpected setsockopt: actual -1 == expected -1
    test_update_ca:FAIL:ca1_ca1_cnt unexpected ca1_ca1_cnt: actual 0 <= expected 0
    torvalds#29/9    bpf_tcp_ca/update_ca:FAIL
    torvalds#29      bpf_tcp_ca:FAIL
    Caught signal torvalds#11!
    Stack trace:
    <backtrace not supported>
    [17900.243360] do_page_fault(): sending SIGSEGV to test_progs for invalid read access from 0000000000000020
    [17900.243799] epc = 00000001204f817c in test_progs[4f817c,120000000+c53000]
    [17900.244209] ra  = 00000001204f8108 in test_progs[4f8108,120000000+c53000]
    Segmentation fault

Add the missing error handling to allow these tests to fail gracefully.

Fixes: 06da9f3 ("selftests/bpf: Test switching TCP Congestion Control algorithms")
Signed-off-by: Tony Ambardar <tony.ambardar@gmail.com>
  • Loading branch information
Tony Ambardar committed Jul 2, 2024
1 parent 2ce34c6 commit d6c49fa
Showing 1 changed file with 18 additions and 7 deletions.
25 changes: 18 additions & 7 deletions tools/testing/selftests/bpf/prog_tests/bpf_tcp_ca.c
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,10 @@ static void test_update_ca(void)
return;

link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
ASSERT_OK_PTR(link, "attach_struct_ops");
if (!ASSERT_OK_PTR(link, "attach_struct_ops")) {
tcp_ca_update__destroy(skel);
return;
}

do_test("tcp_ca_update", NULL);
saved_ca1_cnt = skel->bss->ca1_cnt;
Expand Down Expand Up @@ -336,7 +339,10 @@ static void test_update_wrong(void)
return;

link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
ASSERT_OK_PTR(link, "attach_struct_ops");
if (!ASSERT_OK_PTR(link, "attach_struct_ops")) {
tcp_ca_update__destroy(skel);
return;
}

do_test("tcp_ca_update", NULL);
saved_ca1_cnt = skel->bss->ca1_cnt;
Expand All @@ -355,25 +361,27 @@ static void test_update_wrong(void)
static void test_mixed_links(void)
{
struct tcp_ca_update *skel;
struct bpf_link *link, *link_nl;
struct bpf_link *link = NULL, *link_nl = NULL;
int err;

skel = tcp_ca_update__open_and_load();
if (!ASSERT_OK_PTR(skel, "open"))
return;

link_nl = bpf_map__attach_struct_ops(skel->maps.ca_no_link);
ASSERT_OK_PTR(link_nl, "attach_struct_ops_nl");
if (!ASSERT_OK_PTR(link_nl, "attach_struct_ops_nl"))
goto done;

link = bpf_map__attach_struct_ops(skel->maps.ca_update_1);
ASSERT_OK_PTR(link, "attach_struct_ops");
if (!ASSERT_OK_PTR(link, "attach_struct_ops"))
goto done;

do_test("tcp_ca_update", NULL);
ASSERT_GT(skel->bss->ca1_cnt, 0, "ca1_ca1_cnt");

err = bpf_link__update_map(link, skel->maps.ca_no_link);
ASSERT_ERR(err, "update_map");

done:
bpf_link__destroy(link);
bpf_link__destroy(link_nl);
tcp_ca_update__destroy(skel);
Expand Down Expand Up @@ -418,7 +426,10 @@ static void test_link_replace(void)
bpf_link__destroy(link);

link = bpf_map__attach_struct_ops(skel->maps.ca_update_2);
ASSERT_OK_PTR(link, "attach_struct_ops_2nd");
if (!ASSERT_OK_PTR(link, "attach_struct_ops_2nd")) {
tcp_ca_update__destroy(skel);
return;
}

/* BPF_F_REPLACE with a wrong old map Fd. It should fail!
*
Expand Down

0 comments on commit d6c49fa

Please sign in to comment.