1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2026 Christian Brauner */ 3 4 #include <errno.h> 5 #include <string.h> 6 #include <unistd.h> 7 #include <sys/xattr.h> 8 #include <sys/socket.h> 9 #include <netinet/in.h> 10 #include <test_progs.h> 11 12 #include "sock_read_xattr.skel.h" 13 14 static const char xattr_value[] = "bpf_sock_value"; 15 static const char xattr_name[] = "user.bpf_test"; 16 17 static void test_read_sock_xattr(void) 18 { 19 struct sockaddr_in addr = {}; 20 struct sock_read_xattr *skel = NULL; 21 struct bpf_link *link = NULL; 22 int sock_fd = -1, err; 23 24 sock_fd = socket(AF_INET, SOCK_STREAM, 0); 25 if (!ASSERT_OK_FD(sock_fd, "socket")) 26 return; 27 28 err = fsetxattr(sock_fd, xattr_name, xattr_value, sizeof(xattr_value), 0); 29 if (!ASSERT_OK(err, "fsetxattr")) 30 goto out; 31 32 skel = sock_read_xattr__open_and_load(); 33 if (!ASSERT_OK_PTR(skel, "sock_read_xattr__open_and_load")) 34 goto out; 35 36 skel->bss->monitored_pid = sys_gettid(); 37 38 /* Only attach the functional program; the verifier-only programs 39 * above are not pid-gated and would clobber the shared globals. 40 */ 41 link = bpf_program__attach(skel->progs.read_sock_xattr); 42 if (!ASSERT_OK_PTR(link, "attach read_sock_xattr")) 43 goto out; 44 45 addr.sin_family = AF_INET; 46 addr.sin_port = htons(1234); 47 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 48 /* Only the lsm/socket_connect hook matters; the connect may fail. */ 49 connect(sock_fd, (struct sockaddr *)&addr, sizeof(addr)); 50 51 ASSERT_EQ(skel->data->read_ret, sizeof(xattr_value), "read_ret"); 52 ASSERT_STREQ(skel->bss->value, xattr_value, "value"); 53 54 out: 55 bpf_link__destroy(link); 56 if (sock_fd >= 0) 57 close(sock_fd); 58 sock_read_xattr__destroy(skel); 59 } 60 61 void test_sock_xattr(void) 62 { 63 RUN_TESTS(sock_read_xattr); 64 65 if (test__start_subtest("read_sock_xattr")) 66 test_read_sock_xattr(); 67 } 68