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