Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/bpf: Attach to socketcall() in test_probe_user

test_probe_user fails on architectures where libc uses
socketcall(SYS_CONNECT) instead of connect(). Fix by attaching
to socketcall as well.

Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Link: https://lore.kernel.org/bpf/20220726134008.256968-3-iii@linux.ibm.com

authored by

Ilya Leoshkevich and committed by
Daniel Borkmann
d295daf5 2d369b4b

+51 -13
+24 -11
tools/testing/selftests/bpf/prog_tests/probe_user.c
··· 4 4 /* TODO: corrupts other tests uses connect() */ 5 5 void serial_test_probe_user(void) 6 6 { 7 - const char *prog_name = "handle_sys_connect"; 7 + static const char *const prog_names[] = { 8 + "handle_sys_connect", 9 + #if defined(__s390x__) 10 + "handle_sys_socketcall", 11 + #endif 12 + }; 13 + enum { prog_count = ARRAY_SIZE(prog_names) }; 8 14 const char *obj_file = "./test_probe_user.o"; 9 15 DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts, ); 10 16 int err, results_map_fd, sock_fd, duration = 0; 11 17 struct sockaddr curr, orig, tmp; 12 18 struct sockaddr_in *in = (struct sockaddr_in *)&curr; 13 - struct bpf_link *kprobe_link = NULL; 14 - struct bpf_program *kprobe_prog; 19 + struct bpf_link *kprobe_links[prog_count] = {}; 20 + struct bpf_program *kprobe_progs[prog_count]; 15 21 struct bpf_object *obj; 16 22 static const int zero = 0; 23 + size_t i; 17 24 18 25 obj = bpf_object__open_file(obj_file, &opts); 19 26 if (!ASSERT_OK_PTR(obj, "obj_open_file")) 20 27 return; 21 28 22 - kprobe_prog = bpf_object__find_program_by_name(obj, prog_name); 23 - if (CHECK(!kprobe_prog, "find_probe", 24 - "prog '%s' not found\n", prog_name)) 25 - goto cleanup; 29 + for (i = 0; i < prog_count; i++) { 30 + kprobe_progs[i] = 31 + bpf_object__find_program_by_name(obj, prog_names[i]); 32 + if (CHECK(!kprobe_progs[i], "find_probe", 33 + "prog '%s' not found\n", prog_names[i])) 34 + goto cleanup; 35 + } 26 36 27 37 err = bpf_object__load(obj); 28 38 if (CHECK(err, "obj_load", "err %d\n", err)) ··· 43 33 "err %d\n", results_map_fd)) 44 34 goto cleanup; 45 35 46 - kprobe_link = bpf_program__attach(kprobe_prog); 47 - if (!ASSERT_OK_PTR(kprobe_link, "attach_kprobe")) 48 - goto cleanup; 36 + for (i = 0; i < prog_count; i++) { 37 + kprobe_links[i] = bpf_program__attach(kprobe_progs[i]); 38 + if (!ASSERT_OK_PTR(kprobe_links[i], "attach_kprobe")) 39 + goto cleanup; 40 + } 49 41 50 42 memset(&curr, 0, sizeof(curr)); 51 43 in->sin_family = AF_INET; ··· 81 69 inet_ntoa(in->sin_addr), ntohs(in->sin_port))) 82 70 goto cleanup; 83 71 cleanup: 84 - bpf_link__destroy(kprobe_link); 72 + for (i = 0; i < prog_count; i++) 73 + bpf_link__destroy(kprobe_links[i]); 85 74 bpf_object__close(obj); 86 75 }
+27 -2
tools/testing/selftests/bpf/progs/test_probe_user.c
··· 7 7 8 8 static struct sockaddr_in old; 9 9 10 - SEC("ksyscall/connect") 11 - int BPF_KSYSCALL(handle_sys_connect, int fd, struct sockaddr_in *uservaddr, int addrlen) 10 + static int handle_sys_connect_common(struct sockaddr_in *uservaddr) 12 11 { 13 12 struct sockaddr_in new; 14 13 ··· 17 18 18 19 return 0; 19 20 } 21 + 22 + SEC("ksyscall/connect") 23 + int BPF_KSYSCALL(handle_sys_connect, int fd, struct sockaddr_in *uservaddr, 24 + int addrlen) 25 + { 26 + return handle_sys_connect_common(uservaddr); 27 + } 28 + 29 + #if defined(bpf_target_s390) 30 + #ifndef SYS_CONNECT 31 + #define SYS_CONNECT 3 32 + #endif 33 + 34 + SEC("ksyscall/socketcall") 35 + int BPF_KSYSCALL(handle_sys_socketcall, int call, unsigned long *args) 36 + { 37 + if (call == SYS_CONNECT) { 38 + struct sockaddr_in *uservaddr; 39 + 40 + bpf_probe_read_user(&uservaddr, sizeof(uservaddr), &args[1]); 41 + return handle_sys_connect_common(uservaddr); 42 + } 43 + 44 + return 0; 45 + } 46 + #endif 20 47 21 48 char _license[] SEC("license") = "GPL";