]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-namespace.c
fd-uitl: rename PIPE_EBADF → EBADF_PAIR, and add EBADF_TRIPLET
[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) {
71136404 86 _cleanup_close_pair_ int s[2] = EBADF_PAIR;
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) {
79d956db
LP
152 static const NamespaceParameters p = {
153 .runtime_scope = RUNTIME_SCOPE_SYSTEM,
806aea38
KK
154 .protect_kernel_logs = true,
155 };
79d956db
LP
156 pid_t pid;
157 int r;
806aea38
KK
158
159 if (geteuid() > 0) {
160 (void) log_tests_skipped("not root");
161 return;
162 }
163
164 /* In a container we likely don't have access to /dev/kmsg */
165 if (detect_container() > 0) {
166 (void) log_tests_skipped("in container");
167 return;
168 }
169
806aea38
KK
170 pid = fork();
171 assert_se(pid >= 0);
172
173 if (pid == 0) {
254d1313 174 _cleanup_close_ int fd = -EBADF;
806aea38
KK
175
176 fd = open("/dev/kmsg", O_RDONLY | O_CLOEXEC);
177 assert_se(fd > 0);
178
79d956db 179 r = setup_namespace(&p, NULL);
806aea38
KK
180 assert_se(r == 0);
181
182 assert_se(setresuid(UID_NOBODY, UID_NOBODY, UID_NOBODY) >= 0);
183 assert_se(open("/dev/kmsg", O_RDONLY | O_CLOEXEC) < 0);
184 assert_se(errno == EACCES);
185
186 _exit(EXIT_SUCCESS);
187 }
188
189 assert_se(wait_for_terminate_and_check("ns-kernellogs", pid, WAIT_LOG) == EXIT_SUCCESS);
d8c9d3a4
ZJS
190}
191
99839c7e
LP
192static int intro(void) {
193 if (!have_namespaces())
194 return log_tests_skipped("Don't have namespace support");
195
196 return EXIT_SUCCESS;
197}
198
e85fdacc 199DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro);