1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2023 Hengqi Chen */ 3 4 #include <test_progs.h> 5 #include "test_uprobe.skel.h" 6 7 static FILE *urand_spawn(int *pid) 8 { 9 FILE *f; 10 11 /* urandom_read's stdout is wired into f */ 12 f = popen("./urandom_read 1 report-pid", "r"); 13 if (!f) 14 return NULL; 15 16 if (fscanf(f, "%d", pid) != 1) { 17 pclose(f); 18 errno = EINVAL; 19 return NULL; 20 } 21 22 return f; 23 } 24 25 static int urand_trigger(FILE **urand_pipe) 26 { 27 int exit_code; 28 29 /* pclose() waits for child process to exit and returns their exit code */ 30 exit_code = pclose(*urand_pipe); 31 *urand_pipe = NULL; 32 33 return exit_code; 34 } 35 36 void test_uprobe(void) 37 { 38 LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts); 39 struct test_uprobe *skel; 40 FILE *urand_pipe = NULL; 41 int urand_pid = 0, err; 42 43 skel = test_uprobe__open_and_load(); 44 if (!ASSERT_OK_PTR(skel, "skel_open")) 45 return; 46 47 urand_pipe = urand_spawn(&urand_pid); 48 if (!ASSERT_OK_PTR(urand_pipe, "urand_spawn")) 49 goto cleanup; 50 51 skel->bss->my_pid = urand_pid; 52 53 /* Manual attach uprobe to urandlib_api 54 * There are two `urandlib_api` symbols in .dynsym section: 55 * - urandlib_api@LIBURANDOM_READ_1.0.0 56 * - urandlib_api@@LIBURANDOM_READ_2.0.0 57 * Both are global bind and would cause a conflict if user 58 * specify the symbol name without a version suffix 59 */ 60 uprobe_opts.func_name = "urandlib_api"; 61 skel->links.test4 = bpf_program__attach_uprobe_opts(skel->progs.test4, 62 urand_pid, 63 "./liburandom_read.so", 64 0 /* offset */, 65 &uprobe_opts); 66 if (!ASSERT_ERR_PTR(skel->links.test4, "urandlib_api_attach_conflict")) 67 goto cleanup; 68 69 uprobe_opts.func_name = "urandlib_api@LIBURANDOM_READ_1.0.0"; 70 skel->links.test4 = bpf_program__attach_uprobe_opts(skel->progs.test4, 71 urand_pid, 72 "./liburandom_read.so", 73 0 /* offset */, 74 &uprobe_opts); 75 if (!ASSERT_OK_PTR(skel->links.test4, "urandlib_api_attach_ok")) 76 goto cleanup; 77 78 /* Auto attach 3 u[ret]probes to urandlib_api_sameoffset */ 79 err = test_uprobe__attach(skel); 80 if (!ASSERT_OK(err, "skel_attach")) 81 goto cleanup; 82 83 /* trigger urandom_read */ 84 ASSERT_OK(urand_trigger(&urand_pipe), "urand_exit_code"); 85 86 ASSERT_EQ(skel->bss->test1_result, 1, "urandlib_api_sameoffset"); 87 ASSERT_EQ(skel->bss->test2_result, 1, "urandlib_api_sameoffset@v1"); 88 ASSERT_EQ(skel->bss->test3_result, 3, "urandlib_api_sameoffset@@v2"); 89 ASSERT_EQ(skel->bss->test4_result, 1, "urandlib_api"); 90 91 cleanup: 92 if (urand_pipe) 93 pclose(urand_pipe); 94 test_uprobe__destroy(skel); 95 } 96