Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
selftests/bpf: Add tests for symbol versioning for uprobe
This exercises the newly added dynsym symbol versioning logics. Now we accept symbols in form of func, func@LIB_VERSION or func@@LIB_VERSION. The test rely on liburandom_read.so. For liburandom_read.so, we have: $ nm -D liburandom_read.so w __cxa_finalize@GLIBC_2.17 w __gmon_start__ w _ITM_deregisterTMCloneTable w _ITM_registerTMCloneTable 0000000000000000 A LIBURANDOM_READ_1.0.0 0000000000000000 A LIBURANDOM_READ_2.0.0 000000000000081c T urandlib_api@@LIBURANDOM_READ_2.0.0 0000000000000814 T urandlib_api@LIBURANDOM_READ_1.0.0 0000000000000824 T urandlib_api_sameoffset@LIBURANDOM_READ_1.0.0 0000000000000824 T urandlib_api_sameoffset@@LIBURANDOM_READ_2.0.0 000000000000082c T urandlib_read_without_sema@@LIBURANDOM_READ_1.0.0 00000000000007c4 T urandlib_read_with_sema@@LIBURANDOM_READ_1.0.0 0000000000011018 D urandlib_read_with_sema_semaphore@@LIBURANDOM_READ_1.0.0 For `urandlib_api`, specifying `urandlib_api` will cause a conflict because there are two symbols named urandlib_api and both are global bind. For `urandlib_api_sameoffset`, there are also two symbols in the .so, but both are at the same offset and essentially they refer to the same function so no conflict. Reviewed-by: Alan Maguire <alan.maguire@oracle.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Hengqi Chen <hengqi.chen@gmail.com>
- Loading branch information
1 parent
15c1a29
commit 8050551
Showing
6 changed files
with
224 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
LIBURANDOM_READ_1.0.0 { | ||
global: | ||
urandlib_api; | ||
urandlib_api_sameoffset; | ||
urandlib_read_without_sema; | ||
urandlib_read_with_sema; | ||
urandlib_read_with_sema_semaphore; | ||
local: | ||
*; | ||
}; | ||
|
||
LIBURANDOM_READ_2.0.0 { | ||
global: | ||
urandlib_api; | ||
} LIBURANDOM_READ_1.0.0; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2023 Hengqi Chen */ | ||
|
||
#include <test_progs.h> | ||
#include "test_uprobe.skel.h" | ||
|
||
static FILE *urand_spawn(int *pid) | ||
{ | ||
FILE *f; | ||
|
||
/* urandom_read's stdout is wired into f */ | ||
f = popen("./urandom_read 1 report-pid", "r"); | ||
if (!f) | ||
return NULL; | ||
|
||
if (fscanf(f, "%d", pid) != 1) { | ||
pclose(f); | ||
errno = EINVAL; | ||
return NULL; | ||
} | ||
|
||
return f; | ||
} | ||
|
||
static int urand_trigger(FILE **urand_pipe) | ||
{ | ||
int exit_code; | ||
|
||
/* pclose() waits for child process to exit and returns their exit code */ | ||
exit_code = pclose(*urand_pipe); | ||
*urand_pipe = NULL; | ||
|
||
return exit_code; | ||
} | ||
|
||
void test_uprobe(void) | ||
{ | ||
LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); | ||
struct test_uprobe *skel; | ||
FILE *urand_pipe = NULL; | ||
int urand_pid = 0, err; | ||
|
||
skel = test_uprobe__open_and_load(); | ||
if (!ASSERT_OK_PTR(skel, "skel_open")) | ||
return; | ||
|
||
urand_pipe = urand_spawn(&urand_pid); | ||
if (!ASSERT_OK_PTR(urand_pipe, "urand_spawn")) | ||
goto cleanup; | ||
|
||
skel->bss->my_pid = urand_pid; | ||
|
||
/* Manual attach uprobe to urandlib_api | ||
* There are two `urandlib_api` symbols in .dynsym section: | ||
* - urandlib_api@LIBURANDOM_READ_1.0.0 | ||
* - urandlib_api@@LIBURANDOM_READ_2.0.0 | ||
* Both are global bind and would cause a conflict if user | ||
* specify the symbol name without a version suffix | ||
*/ | ||
uprobe_opts.func_name = "urandlib_api"; | ||
skel->links.test4 = bpf_program__attach_uprobe_opts(skel->progs.test4, | ||
urand_pid, | ||
"./liburandom_read.so", | ||
0 /* offset */, | ||
&uprobe_opts); | ||
if (!ASSERT_ERR_PTR(skel->links.test4, "urandlib_api_attach_conflict")) | ||
goto cleanup; | ||
|
||
uprobe_opts.func_name = "urandlib_api@LIBURANDOM_READ_1.0.0"; | ||
skel->links.test4 = bpf_program__attach_uprobe_opts(skel->progs.test4, | ||
urand_pid, | ||
"./liburandom_read.so", | ||
0 /* offset */, | ||
&uprobe_opts); | ||
if (!ASSERT_OK_PTR(skel->links.test4, "urandlib_api_attach_ok")) | ||
goto cleanup; | ||
|
||
/* Auto attach 3 u[ret]probes to urandlib_api_sameoffset */ | ||
err = test_uprobe__attach(skel); | ||
if (!ASSERT_OK(err, "skel_attach")) | ||
goto cleanup; | ||
|
||
/* trigger urandom_read */ | ||
ASSERT_OK(urand_trigger(&urand_pipe), "urand_exit_code"); | ||
|
||
ASSERT_EQ(skel->bss->test1_result, 1, "urandlib_api_sameoffset"); | ||
ASSERT_EQ(skel->bss->test2_result, 1, "urandlib_api_sameoffset@v1"); | ||
ASSERT_EQ(skel->bss->test3_result, 3, "urandlib_api_sameoffset@@v2"); | ||
ASSERT_EQ(skel->bss->test4_result, 1, "urandlib_api"); | ||
|
||
cleanup: | ||
if (urand_pipe) | ||
pclose(urand_pipe); | ||
test_uprobe__destroy(skel); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// SPDX-License-Identifier: GPL-2.0 | ||
/* Copyright (c) 2023 Hengqi Chen */ | ||
|
||
#include "vmlinux.h" | ||
#include <bpf/bpf_helpers.h> | ||
#include <bpf/bpf_tracing.h> | ||
|
||
pid_t my_pid = 0; | ||
|
||
int test1_result = 0; | ||
int test2_result = 0; | ||
int test3_result = 0; | ||
int test4_result = 0; | ||
|
||
SEC("uprobe/./liburandom_read.so:urandlib_api_sameoffset") | ||
int BPF_UPROBE(test1) | ||
{ | ||
pid_t pid = bpf_get_current_pid_tgid() >> 32; | ||
|
||
if (pid != my_pid) | ||
return 0; | ||
|
||
test1_result = 1; | ||
return 0; | ||
} | ||
|
||
SEC("uprobe/./liburandom_read.so:urandlib_api_sameoffset@LIBURANDOM_READ_1.0.0") | ||
int BPF_UPROBE(test2) | ||
{ | ||
pid_t pid = bpf_get_current_pid_tgid() >> 32; | ||
|
||
if (pid != my_pid) | ||
return 0; | ||
|
||
test2_result = 1; | ||
return 0; | ||
} | ||
|
||
SEC("uretprobe/./liburandom_read.so:urandlib_api_sameoffset@@LIBURANDOM_READ_2.0.0") | ||
int BPF_URETPROBE(test3, int ret) | ||
{ | ||
pid_t pid = bpf_get_current_pid_tgid() >> 32; | ||
|
||
if (pid != my_pid) | ||
return 0; | ||
|
||
test3_result = ret; | ||
return 0; | ||
} | ||
|
||
SEC("uprobe") | ||
int BPF_UPROBE(test4) | ||
{ | ||
pid_t pid = bpf_get_current_pid_tgid() >> 32; | ||
|
||
if (pid != my_pid) | ||
return 0; | ||
|
||
test4_result = 1; | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters