]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-namespace.c
MountAPIVFS: always mount a tmpfs on /run
[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"
07630cea 14#include "util.h"
806aea38 15#include "virt.h"
d8c9d3a4 16
56a13a49
ZJS
17static 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
d8c9d3a4
ZJS
30static void test_tmpdir(const char *id, const char *A, const char *B) {
31 _cleanup_free_ char *a, *b;
613b411c
LP
32 struct stat x, y;
33 char *c, *d;
d8c9d3a4 34
613b411c 35 assert_se(setup_tmp_dirs(id, &a, &b) == 0);
d8c9d3a4 36
613b411c
LP
37 assert_se(stat(a, &x) >= 0);
38 assert_se(stat(b, &y) >= 0);
d8c9d3a4 39
613b411c
LP
40 assert_se(S_ISDIR(x.st_mode));
41 assert_se(S_ISDIR(y.st_mode));
d8c9d3a4 42
56a13a49
ZJS
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));
1d6cc5d0 49 assert_se(FLAGS_SET(x.st_mode, 01777));
56a13a49
ZJS
50 assert_se(rmdir(c) >= 0);
51 assert_se(rmdir(a) >= 0);
52 }
613b411c 53
56a13a49
ZJS
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));
1d6cc5d0 60 assert_se(FLAGS_SET(y.st_mode, 01777));
56a13a49
ZJS
61 assert_se(rmdir(d) >= 0);
62 assert_se(rmdir(b) >= 0);
63 }
613b411c
LP
64}
65
806aea38 66static void test_netns(void) {
3d94f76c 67 _cleanup_close_pair_ int s[2] = { -1, -1 };
613b411c
LP
68 pid_t pid1, pid2, pid3;
69 int r, n = 0;
70 siginfo_t si;
71
806aea38
KK
72 if (geteuid() > 0) {
73 (void) log_tests_skipped("not root");
74 return;
75 }
613b411c
LP
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);
806aea38
KK
122}
123
124static 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,
18d73705 153 NULL,
806aea38
KK
154 NULL,
155 &ns_info,
156 NULL,
157 NULL,
158 NULL,
159 NULL,
160 NULL, 0,
161 NULL, 0,
b3d13314 162 NULL, 0,
806aea38
KK
163 NULL,
164 NULL,
91dd5f7c 165 NULL,
bbb4e7f3 166 NULL,
806aea38 167 0,
0389f4fa
LB
168 NULL,
169 0,
170 NULL,
171 NULL,
806aea38 172 0,
d4d55b0d
LB
173 NULL,
174 NULL,
175 0,
806aea38
KK
176 NULL);
177 assert_se(r == 0);
178
179 assert_se(setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY) >= 0);
180 assert_se(open("/dev/kmsg", O_RDONLY | O_CLOEXEC) < 0);
181 assert_se(errno == EACCES);
182
183 _exit(EXIT_SUCCESS);
184 }
185
186 assert_se(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG) == EXIT_SUCCESS);
d8c9d3a4
ZJS
187}
188
189int main(int argc, char *argv[]) {
6b46ea73
LP
190 sd_id128_t bid;
191 char boot_id[SD_ID128_STRING_MAX];
192 _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *zz = NULL;
d8c9d3a4 193
6d7c4033 194 test_setup_logging(LOG_INFO);
d2528deb 195
56a13a49
ZJS
196 test_namespace_cleanup_tmpdir();
197
5f00dc4d
LP
198 if (!have_namespaces()) {
199 log_tests_skipped("Don't have namespace support");
200 return EXIT_TEST_SKIP;
201 }
202
6b46ea73
LP
203 assert_se(sd_id128_get_boot(&bid) >= 0);
204 sd_id128_to_string(bid, boot_id);
205
605405c6
ZJS
206 x = strjoin("/tmp/systemd-private-", boot_id, "-abcd.service-");
207 y = strjoin("/var/tmp/systemd-private-", boot_id, "-abcd.service-");
6b46ea73
LP
208 assert_se(x && y);
209
210 test_tmpdir("abcd.service", x, y);
211
605405c6
ZJS
212 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-");
213 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-");
6b46ea73
LP
214
215 assert_se(z && zz);
216
217 test_tmpdir("sys-devices-pci0000:00-0000:00:1a.0-usb3-3\\x2d1-3\\x2d1:1.0-bluetooth-hci0.device", z, zz);
d8c9d3a4 218
806aea38
KK
219 test_netns();
220 test_protect_kernel_logs();
221
222 return EXIT_SUCCESS;
d8c9d3a4 223}