]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-namespace.c
add ipv6 range element creation test cases
[thirdparty/systemd.git] / src / test / test-namespace.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <fcntl.h>
4 #include <sys/socket.h>
5 #include <sys/stat.h>
6
7 #include "alloc-util.h"
8 #include "fd-util.h"
9 #include "namespace.h"
10 #include "process-util.h"
11 #include "string-util.h"
12 #include "tests.h"
13 #include "user-util.h"
14 #include "util.h"
15 #include "virt.h"
16
17 static void test_namespace_cleanup_tmpdir(void) {
18 {
19 _cleanup_(namespace_cleanup_tmpdirp) char *dir;
20 assert_se(dir = strdup(RUN_SYSTEMD_EMPTY));
21 }
22
23 {
24 _cleanup_(namespace_cleanup_tmpdirp) char *dir;
25 assert_se(dir = strdup("/tmp/systemd-test-namespace.XXXXXX"));
26 assert_se(mkdtemp(dir));
27 }
28 }
29
30 static void test_tmpdir(const char *id, const char *A, const char *B) {
31 _cleanup_free_ char *a, *b;
32 struct stat x, y;
33 char *c, *d;
34
35 assert_se(setup_tmp_dirs(id, &a, &b) == 0);
36
37 assert_se(stat(a, &x) >= 0);
38 assert_se(stat(b, &y) >= 0);
39
40 assert_se(S_ISDIR(x.st_mode));
41 assert_se(S_ISDIR(y.st_mode));
42
43 if (!streq(a, RUN_SYSTEMD_EMPTY)) {
44 assert_se(startswith(a, A));
45 assert_se((x.st_mode & 01777) == 0700);
46 c = strjoina(a, "/tmp");
47 assert_se(stat(c, &x) >= 0);
48 assert_se(S_ISDIR(x.st_mode));
49 assert_se(FLAGS_SET(x.st_mode, 01777));
50 assert_se(rmdir(c) >= 0);
51 assert_se(rmdir(a) >= 0);
52 }
53
54 if (!streq(b, RUN_SYSTEMD_EMPTY)) {
55 assert_se(startswith(b, B));
56 assert_se((y.st_mode & 01777) == 0700);
57 d = strjoina(b, "/tmp");
58 assert_se(stat(d, &y) >= 0);
59 assert_se(S_ISDIR(y.st_mode));
60 assert_se(FLAGS_SET(y.st_mode, 01777));
61 assert_se(rmdir(d) >= 0);
62 assert_se(rmdir(b) >= 0);
63 }
64 }
65
66 static void test_netns(void) {
67 _cleanup_close_pair_ int s[2] = { -1, -1 };
68 pid_t pid1, pid2, pid3;
69 int r, n = 0;
70 siginfo_t si;
71
72 if (geteuid() > 0) {
73 (void) log_tests_skipped("not root");
74 return;
75 }
76
77 assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, s) >= 0);
78
79 pid1 = fork();
80 assert_se(pid1 >= 0);
81
82 if (pid1 == 0) {
83 r = setup_netns(s);
84 assert_se(r >= 0);
85 _exit(r);
86 }
87
88 pid2 = fork();
89 assert_se(pid2 >= 0);
90
91 if (pid2 == 0) {
92 r = setup_netns(s);
93 assert_se(r >= 0);
94 exit(r);
95 }
96
97 pid3 = fork();
98 assert_se(pid3 >= 0);
99
100 if (pid3 == 0) {
101 r = setup_netns(s);
102 assert_se(r >= 0);
103 exit(r);
104 }
105
106 r = wait_for_terminate(pid1, &si);
107 assert_se(r >= 0);
108 assert_se(si.si_code == CLD_EXITED);
109 n += si.si_status;
110
111 r = wait_for_terminate(pid2, &si);
112 assert_se(r >= 0);
113 assert_se(si.si_code == CLD_EXITED);
114 n += si.si_status;
115
116 r = wait_for_terminate(pid3, &si);
117 assert_se(r >= 0);
118 assert_se(si.si_code == CLD_EXITED);
119 n += si.si_status;
120
121 assert_se(n == 1);
122 }
123
124 static void test_protect_kernel_logs(void) {
125 int r;
126 pid_t pid;
127 static const NamespaceInfo ns_info = {
128 .protect_kernel_logs = true,
129 };
130
131 if (geteuid() > 0) {
132 (void) log_tests_skipped("not root");
133 return;
134 }
135
136 /* In a container we likely don't have access to /dev/kmsg */
137 if (detect_container() > 0) {
138 (void) log_tests_skipped("in container");
139 return;
140 }
141
142
143 pid = fork();
144 assert_se(pid >= 0);
145
146 if (pid == 0) {
147 _cleanup_close_ int fd = -1;
148
149 fd = open("/dev/kmsg", O_RDONLY | O_CLOEXEC);
150 assert_se(fd > 0);
151
152 r = setup_namespace(NULL,
153 NULL,
154 NULL,
155 &ns_info,
156 NULL,
157 NULL,
158 NULL,
159 NULL,
160 NULL, 0,
161 NULL, 0,
162 NULL, 0,
163 NULL,
164 NULL,
165 NULL,
166 NULL,
167 0,
168 NULL,
169 0,
170 NULL,
171 NULL,
172 0,
173 NULL,
174 NULL,
175 NULL,
176 NULL,
177 0,
178 NULL);
179 assert_se(r == 0);
180
181 assert_se(setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY) >= 0);
182 assert_se(open("/dev/kmsg", O_RDONLY | O_CLOEXEC) < 0);
183 assert_se(errno == EACCES);
184
185 _exit(EXIT_SUCCESS);
186 }
187
188 assert_se(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG) == EXIT_SUCCESS);
189 }
190
191 int main(int argc, char *argv[]) {
192 sd_id128_t bid;
193 char boot_id[SD_ID128_STRING_MAX];
194 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;
195
196 test_setup_logging(LOG_INFO);
197
198 test_namespace_cleanup_tmpdir();
199
200 if (!have_namespaces()) {
201 log_tests_skipped("Don't have namespace support");
202 return EXIT_TEST_SKIP;
203 }
204
205 assert_se(sd_id128_get_boot(&bid) >= 0);
206 sd_id128_to_string(bid, boot_id);
207
208 x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-");
209 y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-");
210 assert_se(x && y);
211
212 test_tmpdir("abcd.service", x, y);
213
214 z = strjoin("/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
215 zz = strjoin("/var/tmp/systemd-private-", boot_id, "-sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device-");
216
217 assert_se(z && zz);
218
219 test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);
220
221 test_netns();
222 test_protect_kernel_logs();
223
224 return EXIT_SUCCESS;
225 }