Linux Audio

Check our new training course

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}
v6.8
 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 <sys/fcntl.h>
 
15
16#define STACK_SIZE (1024 * 1024)
17static char child_stack[STACK_SIZE];
18
19static int test_current_pid_tgid(void *args)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20{
21	struct test_ns_current_pid_tgid__bss  *bss;
22	struct test_ns_current_pid_tgid *skel;
23	int err = -1, duration = 0;
24	pid_t tgid, pid;
25	struct stat st;
26
27	skel = test_ns_current_pid_tgid__open_and_load();
28	if (CHECK(!skel, "skel_open_load", "failed to load skeleton\n"))
29		goto cleanup;
30
31	pid = syscall(SYS_gettid);
32	tgid = getpid();
33
34	err = stat("/proc/self/ns/pid", &st);
35	if (CHECK(err, "stat", "failed /proc/self/ns/pid: %d\n", err))
36		goto cleanup;
37
38	bss = skel->bss;
39	bss->dev = st.st_dev;
40	bss->ino = st.st_ino;
41	bss->user_pid = 0;
42	bss->user_tgid = 0;
43
44	err = test_ns_current_pid_tgid__attach(skel);
45	if (CHECK(err, "skel_attach", "skeleton attach failed: %d\n", err))
46		goto cleanup;
47
48	/* trigger tracepoint */
49	usleep(1);
50	ASSERT_EQ(bss->user_pid, pid, "pid");
51	ASSERT_EQ(bss->user_tgid, tgid, "tgid");
52	err = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
54cleanup:
55	 test_ns_current_pid_tgid__destroy(skel);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
57	return err;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58}
59
60static void test_ns_current_pid_tgid_new_ns(void)
61{
62	int wstatus, duration = 0;
63	pid_t cpid;
64
65	/* Create a process in a new namespace, this process
66	 * will be the init process of this new namespace hence will be pid 1.
67	 */
68	cpid = clone(test_current_pid_tgid, child_stack + STACK_SIZE,
69		     CLONE_NEWPID | SIGCHLD, NULL);
70
71	if (CHECK(cpid == -1, "clone", "%s\n", strerror(errno)))
72		return;
73
74	if (CHECK(waitpid(cpid, &wstatus, 0) == -1, "waitpid", "%s\n", strerror(errno)))
75		return;
76
77	if (CHECK(WEXITSTATUS(wstatus) != 0, "newns_pidtgid", "failed"))
78		return;
79}
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81/* TODO: use a different tracepoint */
82void serial_test_ns_current_pid_tgid(void)
83{
84	if (test__start_subtest("ns_current_pid_tgid_root_ns"))
85		test_current_pid_tgid(NULL);
86	if (test__start_subtest("ns_current_pid_tgid_new_ns"))
87		test_ns_current_pid_tgid_new_ns();
 
 
 
 
 
 
 
 
 
 
 
88}