Linux Audio

Check our new training course

Yocto / OpenEmbedded training

Feb 10-13, 2025
Register
Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0
  2/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */
  3
  4#define _GNU_SOURCE
  5#include <test_progs.h>
  6#include "test_ns_current_pid_tgid.skel.h"
  7#include <sys/stat.h>
  8#include <sys/types.h>
  9#include <unistd.h>
 10#include <sys/syscall.h>
 11#include <sched.h>
 12#include <sys/wait.h>
 13#include <sys/mount.h>
 14#include <fcntl.h>
 15#include "network_helpers.h"
 16
 17#define STACK_SIZE (1024 * 1024)
 18static char child_stack[STACK_SIZE];
 19
 20static int get_pid_tgid(pid_t *pid, pid_t *tgid,
 21			struct test_ns_current_pid_tgid__bss *bss)
 22{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 23	struct stat st;
 24	int err;
 25
 26	*pid = sys_gettid();
 27	*tgid = getpid();
 28
 29	err = stat("/proc/self/ns/pid", &st);
 30	if (!ASSERT_OK(err, "stat /proc/self/ns/pid"))
 31		return err;
 32
 33	bss->dev = st.st_dev;
 34	bss->ino = st.st_ino;
 35	bss->user_pid = 0;
 36	bss->user_tgid = 0;
 37	return 0;
 38}
 39
 40static int test_current_pid_tgid_tp(void *args)
 41{
 42	struct test_ns_current_pid_tgid__bss  *bss;
 43	struct test_ns_current_pid_tgid *skel;
 44	int ret = -1, err;
 45	pid_t tgid, pid;
 46
 47	skel = test_ns_current_pid_tgid__open();
 48	if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open"))
 49		return ret;
 50
 51	bpf_program__set_autoload(skel->progs.tp_handler, true);
 52
 53	err = test_ns_current_pid_tgid__load(skel);
 54	if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load"))
 55		goto cleanup;
 56
 57	bss = skel->bss;
 58	if (get_pid_tgid(&pid, &tgid, bss))
 59		goto cleanup;
 60
 61	err = test_ns_current_pid_tgid__attach(skel);
 62	if (!ASSERT_OK(err, "test_ns_current_pid_tgid__attach"))
 63		goto cleanup;
 64
 65	/* trigger tracepoint */
 66	usleep(1);
 67	if (!ASSERT_EQ(bss->user_pid, pid, "pid"))
 68		goto cleanup;
 69	if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid"))
 70		goto cleanup;
 71	ret = 0;
 72
 73cleanup:
 74	test_ns_current_pid_tgid__destroy(skel);
 75	return ret;
 76}
 77
 78static int test_current_pid_tgid_cgrp(void *args)
 79{
 80	struct test_ns_current_pid_tgid__bss *bss;
 81	struct test_ns_current_pid_tgid *skel;
 82	int server_fd = -1, ret = -1, err;
 83	int cgroup_fd = *(int *)args;
 84	pid_t tgid, pid;
 85
 86	skel = test_ns_current_pid_tgid__open();
 87	if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open"))
 88		return ret;
 89
 90	bpf_program__set_autoload(skel->progs.cgroup_bind4, true);
 91
 92	err = test_ns_current_pid_tgid__load(skel);
 93	if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load"))
 94		goto cleanup;
 95
 96	bss = skel->bss;
 97	if (get_pid_tgid(&pid, &tgid, bss))
 
 98		goto cleanup;
 99
100	skel->links.cgroup_bind4 = bpf_program__attach_cgroup(
101		skel->progs.cgroup_bind4, cgroup_fd);
102	if (!ASSERT_OK_PTR(skel->links.cgroup_bind4, "bpf_program__attach_cgroup"))
103		goto cleanup;
104
105	server_fd = start_server(AF_INET, SOCK_STREAM, NULL, 0, 0);
106	if (!ASSERT_GE(server_fd, 0, "start_server"))
107		goto cleanup;
108
109	if (!ASSERT_EQ(bss->user_pid, pid, "pid"))
110		goto cleanup;
111	if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid"))
112		goto cleanup;
113	ret = 0;
114
115cleanup:
116	if (server_fd >= 0)
117		close(server_fd);
118	test_ns_current_pid_tgid__destroy(skel);
119	return ret;
120}
121
122static int test_current_pid_tgid_sk_msg(void *args)
123{
124	int verdict, map, server_fd = -1, client_fd = -1;
125	struct test_ns_current_pid_tgid__bss *bss;
126	static const char send_msg[] = "message";
127	struct test_ns_current_pid_tgid *skel;
128	int ret = -1, err, key = 0;
129	pid_t tgid, pid;
130
131	skel = test_ns_current_pid_tgid__open();
132	if (!ASSERT_OK_PTR(skel, "test_ns_current_pid_tgid__open"))
133		return ret;
134
135	bpf_program__set_autoload(skel->progs.sk_msg, true);
136
137	err = test_ns_current_pid_tgid__load(skel);
138	if (!ASSERT_OK(err, "test_ns_current_pid_tgid__load"))
139		goto cleanup;
140
141	bss = skel->bss;
142	if (get_pid_tgid(&pid, &tgid, skel->bss))
143		goto cleanup;
 
144
145	verdict = bpf_program__fd(skel->progs.sk_msg);
146	map = bpf_map__fd(skel->maps.sock_map);
147	err = bpf_prog_attach(verdict, map, BPF_SK_MSG_VERDICT, 0);
148	if (!ASSERT_OK(err, "prog_attach"))
149		goto cleanup;
150
151	server_fd = start_server(AF_INET6, SOCK_STREAM, "::1", 0, 0);
152	if (!ASSERT_GE(server_fd, 0, "start_server"))
153		goto cleanup;
154
155	client_fd = connect_to_fd(server_fd, 0);
156	if (!ASSERT_GE(client_fd, 0, "connect_to_fd"))
 
 
157		goto cleanup;
 
158
159	err = bpf_map_update_elem(map, &key, &client_fd, BPF_ANY);
160	if (!ASSERT_OK(err, "bpf_map_update_elem"))
161		goto cleanup;
162
163	err = send(client_fd, send_msg, sizeof(send_msg), 0);
164	if (!ASSERT_EQ(err, sizeof(send_msg), "send(msg)"))
165		goto cleanup;
166
167	if (!ASSERT_EQ(bss->user_pid, pid, "pid"))
168		goto cleanup;
169	if (!ASSERT_EQ(bss->user_tgid, tgid, "tgid"))
170		goto cleanup;
171	ret = 0;
172
173cleanup:
174	if (server_fd >= 0)
175		close(server_fd);
176	if (client_fd >= 0)
177		close(client_fd);
178	test_ns_current_pid_tgid__destroy(skel);
179	return ret;
180}
181
182static void test_ns_current_pid_tgid_new_ns(int (*fn)(void *), void *arg)
183{
184	int wstatus;
185	pid_t cpid;
186
187	/* Create a process in a new namespace, this process
188	 * will be the init process of this new namespace hence will be pid 1.
189	 */
190	cpid = clone(fn, child_stack + STACK_SIZE,
191		     CLONE_NEWPID | SIGCHLD, arg);
192
193	if (!ASSERT_NEQ(cpid, -1, "clone"))
194		return;
195
196	if (!ASSERT_NEQ(waitpid(cpid, &wstatus, 0), -1, "waitpid"))
197		return;
198
199	if (!ASSERT_OK(WEXITSTATUS(wstatus), "newns_pidtgid"))
200		return;
201}
202
203static void test_in_netns(int (*fn)(void *), void *arg)
204{
205	struct nstoken *nstoken = NULL;
206
207	SYS(cleanup, "ip netns add ns_current_pid_tgid");
208	SYS(cleanup, "ip -net ns_current_pid_tgid link set dev lo up");
209
210	nstoken = open_netns("ns_current_pid_tgid");
211	if (!ASSERT_OK_PTR(nstoken, "open_netns"))
212		goto cleanup;
213
214	test_ns_current_pid_tgid_new_ns(fn, arg);
215
216cleanup:
217	if (nstoken)
218		close_netns(nstoken);
219	SYS_NOFAIL("ip netns del ns_current_pid_tgid");
220}
221
222/* TODO: use a different tracepoint */
223void serial_test_ns_current_pid_tgid(void)
224{
225	if (test__start_subtest("root_ns_tp"))
226		test_current_pid_tgid_tp(NULL);
227	if (test__start_subtest("new_ns_tp"))
228		test_ns_current_pid_tgid_new_ns(test_current_pid_tgid_tp, NULL);
229	if (test__start_subtest("new_ns_cgrp")) {
230		int cgroup_fd = -1;
231
232		cgroup_fd = test__join_cgroup("/sock_addr");
233		if (ASSERT_GE(cgroup_fd, 0, "join_cgroup")) {
234			test_in_netns(test_current_pid_tgid_cgrp, &cgroup_fd);
235			close(cgroup_fd);
236		}
237	}
238	if (test__start_subtest("new_ns_sk_msg"))
239		test_in_netns(test_current_pid_tgid_sk_msg, NULL);
240}
v5.9
 1// SPDX-License-Identifier: GPL-2.0
 2/* Copyright (c) 2020 Carlos Neira cneirabustos@gmail.com */
 
 
 3#include <test_progs.h>
 
 4#include <sys/stat.h>
 5#include <sys/types.h>
 6#include <unistd.h>
 7#include <sys/syscall.h>
 
 
 
 
 
 
 
 
 8
 9struct bss {
10	__u64 dev;
11	__u64 ino;
12	__u64 pid_tgid;
13	__u64 user_pid_tgid;
14};
15
16void test_ns_current_pid_tgid(void)
17{
18	const char *probe_name = "raw_tracepoint/sys_enter";
19	const char *file = "test_ns_current_pid_tgid.o";
20	int err, key = 0, duration = 0;
21	struct bpf_link *link = NULL;
22	struct bpf_program *prog;
23	struct bpf_map *bss_map;
24	struct bpf_object *obj;
25	struct bss bss;
26	struct stat st;
27	__u64 id;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
29	obj = bpf_object__open_file(file, NULL);
30	if (CHECK(IS_ERR(obj), "obj_open", "err %ld\n", PTR_ERR(obj)))
31		return;
 
 
 
 
 
 
 
 
 
 
32
33	err = bpf_object__load(obj);
34	if (CHECK(err, "obj_load", "err %d errno %d\n", err, errno))
 
35		goto cleanup;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
37	bss_map = bpf_object__find_map_by_name(obj, "test_ns_.bss");
38	if (CHECK(!bss_map, "find_bss_map", "failed\n"))
 
 
39		goto cleanup;
40
41	prog = bpf_object__find_program_by_title(obj, probe_name);
42	if (CHECK(!prog, "find_prog", "prog '%s' not found\n",
43		  probe_name))
44		goto cleanup;
45
46	memset(&bss, 0, sizeof(bss));
47	pid_t tid = syscall(SYS_gettid);
48	pid_t pid = getpid();
 
49
50	id = (__u64) tid << 32 | pid;
51	bss.user_pid_tgid = id;
 
52
53	if (CHECK_FAIL(stat("/proc/self/ns/pid", &st))) {
54		perror("Failed to stat /proc/self/ns/pid");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
55		goto cleanup;
56	}
57
58	bss.dev = st.st_dev;
59	bss.ino = st.st_ino;
 
 
 
60
61	err = bpf_map_update_elem(bpf_map__fd(bss_map), &key, &bss, 0);
62	if (CHECK(err, "setting_bss", "failed to set bss : %d\n", err))
63		goto cleanup;
64
65	link = bpf_program__attach_raw_tracepoint(prog, "sys_enter");
66	if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n",
67		  PTR_ERR(link))) {
68		link = NULL;
69		goto cleanup;
70	}
71
72	/* trigger some syscalls */
73	usleep(1);
 
74
75	err = bpf_map_lookup_elem(bpf_map__fd(bss_map), &key, &bss);
76	if (CHECK(err, "set_bss", "failed to get bss : %d\n", err))
77		goto cleanup;
78
79	if (CHECK(id != bss.pid_tgid, "Compare user pid/tgid vs. bpf pid/tgid",
80		  "User pid/tgid %llu BPF pid/tgid %llu\n", id, bss.pid_tgid))
 
81		goto cleanup;
 
 
82cleanup:
83	bpf_link__destroy(link);
84	bpf_object__close(obj);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85}