1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2025 Meta Platforms, Inc. and affiliates. */ 3 4 #include <errno.h> 5 #include <fcntl.h> 6 #include <sys/stat.h> 7 #include <string.h> 8 #include <unistd.h> 9 #include <sys/socket.h> 10 #include <sys/xattr.h> 11 12 #include <test_progs.h> 13 14 #include "read_cgroupfs_xattr.skel.h" 15 #include "cgroup_read_xattr.skel.h" 16 17 #define CGROUP_FS_ROOT "/sys/fs/cgroup/" 18 #define CGROUP_FS_PARENT CGROUP_FS_ROOT "foo/" 19 #define CGROUP_FS_CHILD CGROUP_FS_PARENT "bar/" 20 21 static int move_pid_to_cgroup(const char *cgroup_folder, pid_t pid) 22 { 23 char filename[128]; 24 char pid_str[64]; 25 int procs_fd; 26 int ret; 27 28 snprintf(filename, sizeof(filename), "%scgroup.procs", cgroup_folder); 29 snprintf(pid_str, sizeof(pid_str), "%d", pid); 30 31 procs_fd = open(filename, O_WRONLY | O_APPEND); 32 if (!ASSERT_OK_FD(procs_fd, "open")) 33 return -1; 34 35 ret = write(procs_fd, pid_str, strlen(pid_str)); 36 close(procs_fd); 37 if (!ASSERT_GT(ret, 0, "write cgroup.procs")) 38 return -1; 39 return 0; 40 } 41 42 static void reset_cgroups_and_lo(void) 43 { 44 rmdir(CGROUP_FS_CHILD); 45 rmdir(CGROUP_FS_PARENT); 46 system("ip addr del 1.1.1.1/32 dev lo"); 47 system("ip link set dev lo down"); 48 } 49 50 static const char xattr_value_a[] = "bpf_selftest_value_a"; 51 static const char xattr_value_b[] = "bpf_selftest_value_b"; 52 static const char xattr_name[] = "user.bpf_test"; 53 54 static int setup_cgroups_and_lo(void) 55 { 56 int err; 57 58 err = mkdir(CGROUP_FS_PARENT, 0755); 59 if (!ASSERT_OK(err, "mkdir 1")) 60 goto error; 61 err = mkdir(CGROUP_FS_CHILD, 0755); 62 if (!ASSERT_OK(err, "mkdir 2")) 63 goto error; 64 65 err = setxattr(CGROUP_FS_PARENT, xattr_name, xattr_value_a, 66 strlen(xattr_value_a) + 1, 0); 67 if (!ASSERT_OK(err, "setxattr 1")) 68 goto error; 69 70 err = setxattr(CGROUP_FS_CHILD, xattr_name, xattr_value_b, 71 strlen(xattr_value_b) + 1, 0); 72 if (!ASSERT_OK(err, "setxattr 2")) 73 goto error; 74 75 err = system("ip link set dev lo up"); 76 if (!ASSERT_OK(err, "lo up")) 77 goto error; 78 79 err = system("ip addr add 1.1.1.1 dev lo"); 80 if (!ASSERT_OK(err, "lo addr v4")) 81 goto error; 82 83 err = write_sysctl("/proc/sys/net/ipv4/ping_group_range", "0 0"); 84 if (!ASSERT_OK(err, "write_sysctl")) 85 goto error; 86 87 return 0; 88 error: 89 reset_cgroups_and_lo(); 90 return err; 91 } 92 93 static void test_read_cgroup_xattr(void) 94 { 95 struct sockaddr_in sa4 = { 96 .sin_family = AF_INET, 97 .sin_addr.s_addr = htonl(INADDR_LOOPBACK), 98 }; 99 struct read_cgroupfs_xattr *skel = NULL; 100 pid_t pid = gettid(); 101 int sock_fd = -1; 102 int connect_fd = -1; 103 104 if (!ASSERT_OK(setup_cgroups_and_lo(), "setup_cgroups_and_lo")) 105 return; 106 if (!ASSERT_OK(move_pid_to_cgroup(CGROUP_FS_CHILD, pid), 107 "move_pid_to_cgroup")) 108 goto out; 109 110 skel = read_cgroupfs_xattr__open_and_load(); 111 if (!ASSERT_OK_PTR(skel, "read_cgroupfs_xattr__open_and_load")) 112 goto out; 113 114 skel->bss->target_pid = pid; 115 116 if (!ASSERT_OK(read_cgroupfs_xattr__attach(skel), "read_cgroupfs_xattr__attach")) 117 goto out; 118 119 sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_ICMP); 120 if (!ASSERT_OK_FD(sock_fd, "sock create")) 121 goto out; 122 123 connect_fd = connect(sock_fd, &sa4, sizeof(sa4)); 124 if (!ASSERT_OK_FD(connect_fd, "connect 1")) 125 goto out; 126 close(connect_fd); 127 128 ASSERT_TRUE(skel->bss->found_value_a, "found_value_a"); 129 ASSERT_TRUE(skel->bss->found_value_b, "found_value_b"); 130 131 out: 132 close(connect_fd); 133 close(sock_fd); 134 read_cgroupfs_xattr__destroy(skel); 135 move_pid_to_cgroup(CGROUP_FS_ROOT, pid); 136 reset_cgroups_and_lo(); 137 } 138 139 void test_cgroup_xattr(void) 140 { 141 RUN_TESTS(cgroup_read_xattr); 142 143 if (test__start_subtest("read_cgroupfs_xattr")) 144 test_read_cgroup_xattr(); 145 } 146