xref: /linux/tools/testing/selftests/bpf/prog_tests/cgroup_xattr.c (revision 0d5ec7919f3747193f051036b2301734a4b5e1d6)
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