]>
Commit | Line | Data |
---|---|---|
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 | 16 | TEST(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 | 29 | static 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 |
65 | TEST(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 | 85 | static 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 | 143 | TEST(netns) { |
54c2459d XR |
144 | test_shareable_ns(CLONE_NEWNET); |
145 | } | |
146 | ||
d19bff65 | 147 | TEST(ipcns) { |
54c2459d XR |
148 | test_shareable_ns(CLONE_NEWIPC); |
149 | } | |
150 | ||
d19bff65 | 151 | TEST(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 |
192 | static 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 | 199 | DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); |