1 // SPDX-License-Identifier: GPL-2.0 2 #include <test_progs.h> 3 4 void test_probe_user(void) 5 { 6 static const char *const prog_names[] = { 7 "handle_sys_connect", 8 #if defined(__s390x__) 9 "handle_sys_socketcall", 10 #endif 11 }; 12 enum { prog_count = ARRAY_SIZE(prog_names) }; 13 const char *obj_file = "./test_probe_user.bpf.o"; 14 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, ); 15 int err, results_map_fd, sock_fd, duration = 0; 16 struct sockaddr curr, orig, tmp; 17 struct sockaddr_in *in = (struct sockaddr_in *)&curr; 18 struct bpf_link *kprobe_links[prog_count] = {}; 19 struct bpf_program *kprobe_progs[prog_count]; 20 struct bpf_object *obj; 21 static const int zero = 0; 22 struct test_pro_bss { 23 struct sockaddr_in old; 24 __u32 test_pid; 25 }; 26 struct test_pro_bss results = {}; 27 size_t i; 28 29 obj = bpf_object__open_file(obj_file, &opts); 30 if (!ASSERT_OK_PTR(obj, "obj_open_file")) 31 return; 32 33 for (i = 0; i < prog_count; i++) { 34 kprobe_progs[i] = 35 bpf_object__find_program_by_name(obj, prog_names[i]); 36 if (CHECK(!kprobe_progs[i], "find_probe", 37 "prog '%s' not found\n", prog_names[i])) 38 goto cleanup; 39 } 40 41 { 42 struct bpf_map *bss_map; 43 struct test_pro_bss bss_init = {}; 44 45 bss_init.test_pid = getpid(); 46 bss_map = bpf_object__find_map_by_name(obj, "test_pro.bss"); 47 if (!ASSERT_OK_PTR(bss_map, "find_bss_map")) 48 goto cleanup; 49 if (!ASSERT_EQ(bpf_map__value_size(bss_map), sizeof(bss_init), 50 "bss_size")) 51 goto cleanup; 52 err = bpf_map__set_initial_value(bss_map, &bss_init, 53 sizeof(bss_init)); 54 if (!ASSERT_OK(err, "set_bss_init")) 55 goto cleanup; 56 } 57 58 err = bpf_object__load(obj); 59 if (CHECK(err, "obj_load", "err %d\n", err)) 60 goto cleanup; 61 62 results_map_fd = bpf_find_map(__func__, obj, "test_pro.bss"); 63 if (CHECK(results_map_fd < 0, "find_bss_map", 64 "err %d\n", results_map_fd)) 65 goto cleanup; 66 67 for (i = 0; i < prog_count; i++) { 68 kprobe_links[i] = bpf_program__attach(kprobe_progs[i]); 69 if (!ASSERT_OK_PTR(kprobe_links[i], "attach_kprobe")) 70 goto cleanup; 71 } 72 73 memset(&curr, 0, sizeof(curr)); 74 in->sin_family = AF_INET; 75 in->sin_port = htons(5555); 76 in->sin_addr.s_addr = inet_addr("255.255.255.255"); 77 memcpy(&orig, &curr, sizeof(curr)); 78 79 sock_fd = socket(AF_INET, SOCK_STREAM, 0); 80 if (CHECK(sock_fd < 0, "create_sock_fd", "err %d\n", sock_fd)) 81 goto cleanup; 82 83 connect(sock_fd, &curr, sizeof(curr)); 84 close(sock_fd); 85 86 err = bpf_map_lookup_elem(results_map_fd, &zero, &results); 87 if (CHECK(err, "get_kprobe_res", 88 "failed to get kprobe res: %d\n", err)) 89 goto cleanup; 90 91 memcpy(&tmp, &results.old, sizeof(tmp)); 92 93 in = (struct sockaddr_in *)&tmp; 94 if (CHECK(memcmp(&tmp, &orig, sizeof(orig)), "check_kprobe_res", 95 "wrong kprobe res from probe read: %s:%u\n", 96 inet_ntoa(in->sin_addr), ntohs(in->sin_port))) 97 goto cleanup; 98 99 memset(&tmp, 0xab, sizeof(tmp)); 100 101 in = (struct sockaddr_in *)&curr; 102 if (CHECK(memcmp(&curr, &tmp, sizeof(tmp)), "check_kprobe_res", 103 "wrong kprobe res from probe write: %s:%u\n", 104 inet_ntoa(in->sin_addr), ntohs(in->sin_port))) 105 goto cleanup; 106 cleanup: 107 for (i = 0; i < prog_count; i++) 108 bpf_link__destroy(kprobe_links[i]); 109 bpf_object__close(obj); 110 } 111