]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-execute.c
Merge pull request #8218 from keszybz/zanata
[thirdparty/systemd.git] / src / test / test-execute.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2014 Ronny Chevalier
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <grp.h>
22 #include <pwd.h>
23 #include <stdio.h>
24 #include <sys/prctl.h>
25 #include <sys/types.h>
26
27 #include "cpu-set-util.h"
28 #include "errno-list.h"
29 #include "fileio.h"
30 #include "fs-util.h"
31 #include "macro.h"
32 #include "manager.h"
33 #include "mkdir.h"
34 #include "path-util.h"
35 #include "rm-rf.h"
36 #if HAVE_SECCOMP
37 #include "seccomp-util.h"
38 #endif
39 #include "stat-util.h"
40 #include "test-helper.h"
41 #include "tests.h"
42 #include "unit.h"
43 #include "util.h"
44 #include "virt.h"
45
46 typedef void (*test_function_t)(Manager *m);
47
48 static void check(Manager *m, Unit *unit, int status_expected, int code_expected) {
49 Service *service = NULL;
50 usec_t ts;
51 usec_t timeout = 2 * USEC_PER_MINUTE;
52
53 assert_se(m);
54 assert_se(unit);
55
56 service = SERVICE(unit);
57 printf("%s\n", unit->id);
58 exec_context_dump(&service->exec_context, stdout, "\t");
59 ts = now(CLOCK_MONOTONIC);
60 while (!IN_SET(service->state, SERVICE_DEAD, SERVICE_FAILED)) {
61 int r;
62 usec_t n;
63
64 r = sd_event_run(m->event, 100 * USEC_PER_MSEC);
65 assert_se(r >= 0);
66
67 n = now(CLOCK_MONOTONIC);
68 if (ts + timeout < n) {
69 log_error("Test timeout when testing %s", unit->id);
70 exit(EXIT_FAILURE);
71 }
72 }
73 exec_status_dump(&service->main_exec_status, stdout, "\t");
74 assert_se(service->main_exec_status.status == status_expected);
75 assert_se(service->main_exec_status.code == code_expected);
76 }
77
78 static bool is_inaccessible_available(void) {
79 char *p;
80
81 FOREACH_STRING(p,
82 "/run/systemd/inaccessible/reg",
83 "/run/systemd/inaccessible/dir",
84 "/run/systemd/inaccessible/chr",
85 "/run/systemd/inaccessible/blk",
86 "/run/systemd/inaccessible/fifo",
87 "/run/systemd/inaccessible/sock"
88 ) {
89 if (access(p, F_OK) < 0)
90 return false;
91 }
92
93 return true;
94 }
95
96 static void test(Manager *m, const char *unit_name, int status_expected, int code_expected) {
97 Unit *unit;
98
99 assert_se(unit_name);
100
101 assert_se(manager_load_unit(m, unit_name, NULL, NULL, &unit) >= 0);
102 assert_se(UNIT_VTABLE(unit)->start(unit) >= 0);
103 check(m, unit, status_expected, code_expected);
104 }
105
106 static void test_exec_bindpaths(Manager *m) {
107 assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0);
108 assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0);
109
110 test(m, "exec-bindpaths.service", 0, CLD_EXITED);
111
112 (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT|REMOVE_PHYSICAL);
113 (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT|REMOVE_PHYSICAL);
114 }
115
116 static void test_exec_cpuaffinity(Manager *m) {
117 _cleanup_cpu_free_ cpu_set_t *c = NULL;
118 unsigned n;
119
120 assert_se(c = cpu_set_malloc(&n));
121 assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n), c) >= 0);
122
123 if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n), c) == 0) {
124 log_notice("Cannot use CPU 0, skipping %s", __func__);
125 return;
126 }
127
128 test(m, "exec-cpuaffinity1.service", 0, CLD_EXITED);
129 test(m, "exec-cpuaffinity2.service", 0, CLD_EXITED);
130
131 if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n), c) == 0 ||
132 CPU_ISSET_S(2, CPU_ALLOC_SIZE(n), c) == 0) {
133 log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__);
134 return;
135 }
136
137 test(m, "exec-cpuaffinity3.service", 0, CLD_EXITED);
138 }
139
140 static void test_exec_workingdirectory(Manager *m) {
141 assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
142
143 test(m, "exec-workingdirectory.service", 0, CLD_EXITED);
144
145 (void) rm_rf("/tmp/test-exec_workingdirectory", REMOVE_ROOT|REMOVE_PHYSICAL);
146 }
147
148 static void test_exec_personality(Manager *m) {
149 #if defined(__x86_64__)
150 test(m, "exec-personality-x86-64.service", 0, CLD_EXITED);
151
152 #elif defined(__s390__)
153 test(m, "exec-personality-s390.service", 0, CLD_EXITED);
154
155 #elif defined(__powerpc64__)
156 # if __BYTE_ORDER == __BIG_ENDIAN
157 test(m, "exec-personality-ppc64.service", 0, CLD_EXITED);
158 # else
159 test(m, "exec-personality-ppc64le.service", 0, CLD_EXITED);
160 # endif
161
162 #elif defined(__aarch64__)
163 test(m, "exec-personality-aarch64.service", 0, CLD_EXITED);
164
165 #elif defined(__i386__)
166 test(m, "exec-personality-x86.service", 0, CLD_EXITED);
167 #else
168 log_notice("Unknown personality, skipping %s", __func__);
169 #endif
170 }
171
172 static void test_exec_ignoresigpipe(Manager *m) {
173 test(m, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED);
174 test(m, "exec-ignoresigpipe-no.service", SIGPIPE, CLD_KILLED);
175 }
176
177 static void test_exec_privatetmp(Manager *m) {
178 assert_se(touch("/tmp/test-exec_privatetmp") >= 0);
179
180 test(m, "exec-privatetmp-yes.service", 0, CLD_EXITED);
181 test(m, "exec-privatetmp-no.service", 0, CLD_EXITED);
182
183 unlink("/tmp/test-exec_privatetmp");
184 }
185
186 static void test_exec_privatedevices(Manager *m) {
187 int r;
188
189 if (detect_container() > 0) {
190 log_notice("Testing in container, skipping %s", __func__);
191 return;
192 }
193 if (!is_inaccessible_available()) {
194 log_notice("Testing without inaccessible, skipping %s", __func__);
195 return;
196 }
197
198 test(m, "exec-privatedevices-yes.service", 0, CLD_EXITED);
199 test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
200
201 /* We use capsh to test if the capabilities are
202 * properly set, so be sure that it exists */
203 r = find_binary("capsh", NULL);
204 if (r < 0) {
205 log_error_errno(r, "Could not find capsh binary, skipping remaining tests in %s: %m", __func__);
206 return;
207 }
208
209 test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
210 test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
211 test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
212 test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
213 }
214
215 static void test_exec_protectkernelmodules(Manager *m) {
216 int r;
217
218 if (detect_container() > 0) {
219 log_notice("Testing in container, skipping %s", __func__);
220 return;
221 }
222 if (!is_inaccessible_available()) {
223 log_notice("Testing without inaccessible, skipping %s", __func__);
224 return;
225 }
226
227 r = find_binary("capsh", NULL);
228 if (r < 0) {
229 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
230 return;
231 }
232
233 test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
234 test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
235 test(m, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED);
236 }
237
238 static void test_exec_readonlypaths(Manager *m) {
239
240 test(m, "exec-readonlypaths-simple.service", 0, CLD_EXITED);
241
242 if (path_is_read_only_fs("/var") > 0) {
243 log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__);
244 return;
245 }
246
247 test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
248 test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
249 test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED);
250 }
251
252 static void test_exec_readwritepaths(Manager *m) {
253
254 if (path_is_read_only_fs("/") > 0) {
255 log_notice("Root directory is readonly, skipping %s", __func__);
256 return;
257 }
258
259 test(m, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED);
260 }
261
262 static void test_exec_inaccessiblepaths(Manager *m) {
263
264 if (!is_inaccessible_available()) {
265 log_notice("Testing without inaccessible, skipping %s", __func__);
266 return;
267 }
268
269 test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
270
271 if (path_is_read_only_fs("/") > 0) {
272 log_notice("Root directory is readonly, skipping remaining tests in %s", __func__);
273 return;
274 }
275
276 test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
277 }
278
279 static void test_exec_temporaryfilesystem(Manager *m) {
280
281 test(m, "exec-temporaryfilesystem-options.service", 0, CLD_EXITED);
282 test(m, "exec-temporaryfilesystem-ro.service", 0, CLD_EXITED);
283 test(m, "exec-temporaryfilesystem-rw.service", 0, CLD_EXITED);
284 test(m, "exec-temporaryfilesystem-usr.service", 0, CLD_EXITED);
285 }
286
287 static void test_exec_systemcallfilter(Manager *m) {
288 #if HAVE_SECCOMP
289 if (!is_seccomp_available()) {
290 log_notice("Seccomp not available, skipping %s", __func__);
291 return;
292 }
293
294 test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
295 test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
296 test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
297 test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
298 test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
299 test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
300 #endif
301 }
302
303 static void test_exec_systemcallerrornumber(Manager *m) {
304 #if HAVE_SECCOMP
305 if (!is_seccomp_available()) {
306 log_notice("Seccomp not available, skipping %s", __func__);
307 return;
308 }
309
310 test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
311 test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
312 #endif
313 }
314
315 static void test_exec_restrictnamespaces(Manager *m) {
316 #if HAVE_SECCOMP
317 if (!is_seccomp_available()) {
318 log_notice("Seccomp not available, skipping %s", __func__);
319 return;
320 }
321
322 test(m, "exec-restrictnamespaces-no.service", 0, CLD_EXITED);
323 test(m, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED);
324 test(m, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED);
325 test(m, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED);
326 #endif
327 }
328
329 static void test_exec_systemcallfilter_system(Manager *m) {
330 #if HAVE_SECCOMP
331 if (!is_seccomp_available()) {
332 log_notice("Seccomp not available, skipping %s", __func__);
333 return;
334 }
335 if (getpwnam("nobody"))
336 test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
337 else if (getpwnam("nfsnobody"))
338 test(m, "exec-systemcallfilter-system-user-nfsnobody.service", 0, CLD_EXITED);
339 else
340 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
341 #endif
342 }
343
344 static void test_exec_user(Manager *m) {
345 if (getpwnam("nobody"))
346 test(m, "exec-user.service", 0, CLD_EXITED);
347 else if (getpwnam("nfsnobody"))
348 test(m, "exec-user-nfsnobody.service", 0, CLD_EXITED);
349 else
350 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
351 }
352
353 static void test_exec_group(Manager *m) {
354 if (getgrnam("nobody"))
355 test(m, "exec-group.service", 0, CLD_EXITED);
356 else if (getgrnam("nfsnobody"))
357 test(m, "exec-group-nfsnobody.service", 0, CLD_EXITED);
358 else if (getgrnam("nogroup"))
359 test(m, "exec-group-nogroup.service", 0, CLD_EXITED);
360 else
361 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody/nogroup group: %m", __func__);
362 }
363
364 static void test_exec_supplementarygroups(Manager *m) {
365 test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
366 test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
367 test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
368 test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
369 test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
370 test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
371 }
372
373 static void test_exec_dynamicuser(Manager *m) {
374 test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
375 test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
376 test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
377 test(m, "exec-dynamicuser-statedir.service", 0, CLD_EXITED);
378
379 test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
380 test(m, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED);
381 (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
382 (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
383 (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
384 (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
385 }
386
387 static void test_exec_environment(Manager *m) {
388 test(m, "exec-environment.service", 0, CLD_EXITED);
389 test(m, "exec-environment-multiple.service", 0, CLD_EXITED);
390 test(m, "exec-environment-empty.service", 0, CLD_EXITED);
391 }
392
393 static void test_exec_environmentfile(Manager *m) {
394 static const char e[] =
395 "VAR1='word1 word2'\n"
396 "VAR2=word3 \n"
397 "# comment1\n"
398 "\n"
399 "; comment2\n"
400 " ; # comment3\n"
401 "line without an equal\n"
402 "VAR3='$word 5 6'\n";
403 int r;
404
405 r = write_string_file("/tmp/test-exec_environmentfile.conf", e, WRITE_STRING_FILE_CREATE);
406 assert_se(r == 0);
407
408 test(m, "exec-environmentfile.service", 0, CLD_EXITED);
409
410 (void) unlink("/tmp/test-exec_environmentfile.conf");
411 }
412
413 static void test_exec_passenvironment(Manager *m) {
414 /* test-execute runs under MANAGER_USER which, by default, forwards all
415 * variables present in the environment, but only those that are
416 * present _at the time it is created_!
417 *
418 * So these PassEnvironment checks are still expected to work, since we
419 * are ensuring the variables are not present at manager creation (they
420 * are unset explicitly in main) and are only set here.
421 *
422 * This is still a good approximation of how a test for MANAGER_SYSTEM
423 * would work.
424 */
425 assert_se(setenv("VAR1", "word1 word2", 1) == 0);
426 assert_se(setenv("VAR2", "word3", 1) == 0);
427 assert_se(setenv("VAR3", "$word 5 6", 1) == 0);
428 test(m, "exec-passenvironment.service", 0, CLD_EXITED);
429 test(m, "exec-passenvironment-repeated.service", 0, CLD_EXITED);
430 test(m, "exec-passenvironment-empty.service", 0, CLD_EXITED);
431 assert_se(unsetenv("VAR1") == 0);
432 assert_se(unsetenv("VAR2") == 0);
433 assert_se(unsetenv("VAR3") == 0);
434 test(m, "exec-passenvironment-absent.service", 0, CLD_EXITED);
435 }
436
437 static void test_exec_umask(Manager *m) {
438 test(m, "exec-umask-default.service", 0, CLD_EXITED);
439 test(m, "exec-umask-0177.service", 0, CLD_EXITED);
440 }
441
442 static void test_exec_runtimedirectory(Manager *m) {
443 test(m, "exec-runtimedirectory.service", 0, CLD_EXITED);
444 test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
445 if (getgrnam("nobody"))
446 test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
447 else if (getgrnam("nfsnobody"))
448 test(m, "exec-runtimedirectory-owner-nfsnobody.service", 0, CLD_EXITED);
449 else
450 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody group: %m", __func__);
451 }
452
453 static void test_exec_capabilityboundingset(Manager *m) {
454 int r;
455
456 r = find_binary("capsh", NULL);
457 if (r < 0) {
458 log_error_errno(r, "Skipping %s, could not find capsh binary: %m", __func__);
459 return;
460 }
461
462 test(m, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED);
463 test(m, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED);
464 test(m, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED);
465 test(m, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED);
466 }
467
468 static void test_exec_capabilityambientset(Manager *m) {
469 int r;
470
471 /* Check if the kernel has support for ambient capabilities. Run
472 * the tests only if that's the case. Clearing all ambient
473 * capabilities is fine, since we are expecting them to be unset
474 * in the first place for the tests. */
475 r = prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_CLEAR_ALL, 0, 0, 0);
476 if (r < 0 && IN_SET(errno, EINVAL, EOPNOTSUPP, ENOSYS)) {
477 log_error("Skipping %s, the kernel does not support ambient capabilities", __func__);
478 return;
479 }
480
481 if (getpwnam("nobody")) {
482 test(m, "exec-capabilityambientset.service", 0, CLD_EXITED);
483 test(m, "exec-capabilityambientset-merge.service", 0, CLD_EXITED);
484 } else if (getpwnam("nfsnobody")) {
485 test(m, "exec-capabilityambientset-nfsnobody.service", 0, CLD_EXITED);
486 test(m, "exec-capabilityambientset-merge-nfsnobody.service", 0, CLD_EXITED);
487 } else
488 log_error_errno(errno, "Skipping %s, could not find nobody/nfsnobody user: %m", __func__);
489 }
490
491 static void test_exec_privatenetwork(Manager *m) {
492 int r;
493
494 r = find_binary("ip", NULL);
495 if (r < 0) {
496 log_error_errno(r, "Skipping %s, could not find ip binary: %m", __func__);
497 return;
498 }
499
500 test(m, "exec-privatenetwork-yes.service", 0, CLD_EXITED);
501 }
502
503 static void test_exec_oomscoreadjust(Manager *m) {
504 test(m, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED);
505 test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
506 }
507
508 static void test_exec_ioschedulingclass(Manager *m) {
509 test(m, "exec-ioschedulingclass-none.service", 0, CLD_EXITED);
510 test(m, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED);
511 test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
512 test(m, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED);
513 }
514
515 static void test_exec_unsetenvironment(Manager *m) {
516 test(m, "exec-unsetenvironment.service", 0, CLD_EXITED);
517 }
518
519 static void test_exec_specifier(Manager *m) {
520 test(m, "exec-specifier.service", 0, CLD_EXITED);
521 test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
522 test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
523 }
524
525 static void test_exec_standardinput(Manager *m) {
526 test(m, "exec-standardinput-data.service", 0, CLD_EXITED);
527 test(m, "exec-standardinput-file.service", 0, CLD_EXITED);
528 }
529
530 static int run_tests(UnitFileScope scope, const test_function_t *tests) {
531 const test_function_t *test = NULL;
532 Manager *m = NULL;
533 int r;
534
535 assert_se(tests);
536
537 r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
538 if (MANAGER_SKIP_TEST(r)) {
539 log_notice_errno(r, "Skipping test: manager_new: %m");
540 return EXIT_TEST_SKIP;
541 }
542 assert_se(r >= 0);
543 assert_se(manager_startup(m, NULL, NULL) >= 0);
544
545 for (test = tests; test && *test; test++)
546 (*test)(m);
547
548 manager_free(m);
549
550 return 0;
551 }
552
553 int main(int argc, char *argv[]) {
554 static const test_function_t user_tests[] = {
555 test_exec_bindpaths,
556 test_exec_capabilityambientset,
557 test_exec_capabilityboundingset,
558 test_exec_cpuaffinity,
559 test_exec_environment,
560 test_exec_environmentfile,
561 test_exec_group,
562 test_exec_ignoresigpipe,
563 test_exec_inaccessiblepaths,
564 test_exec_ioschedulingclass,
565 test_exec_oomscoreadjust,
566 test_exec_passenvironment,
567 test_exec_personality,
568 test_exec_privatedevices,
569 test_exec_privatenetwork,
570 test_exec_privatetmp,
571 test_exec_protectkernelmodules,
572 test_exec_readonlypaths,
573 test_exec_readwritepaths,
574 test_exec_restrictnamespaces,
575 test_exec_runtimedirectory,
576 test_exec_standardinput,
577 test_exec_supplementarygroups,
578 test_exec_systemcallerrornumber,
579 test_exec_systemcallfilter,
580 test_exec_temporaryfilesystem,
581 test_exec_umask,
582 test_exec_unsetenvironment,
583 test_exec_user,
584 test_exec_workingdirectory,
585 NULL,
586 };
587 static const test_function_t system_tests[] = {
588 test_exec_dynamicuser,
589 test_exec_specifier,
590 test_exec_systemcallfilter_system,
591 NULL,
592 };
593 int r;
594
595 log_set_max_level(LOG_DEBUG);
596 log_parse_environment();
597 log_open();
598
599 (void) unsetenv("USER");
600 (void) unsetenv("LOGNAME");
601
602 /* It is needed otherwise cgroup creation fails */
603 if (getuid() != 0) {
604 puts("Skipping test: not root");
605 return EXIT_TEST_SKIP;
606 }
607
608 r = enter_cgroup_subroot();
609 if (r == -ENOMEDIUM) {
610 puts("Skipping test: cgroupfs not available");
611 return EXIT_TEST_SKIP;
612 }
613
614 assert_se(setenv("XDG_RUNTIME_DIR", "/tmp/", 1) == 0);
615 assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0);
616
617 /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
618 * cases, otherwise (and if they are present in the environment),
619 * `manager_default_environment` will copy them into the default
620 * environment which is passed to each created job, which will make the
621 * tests that expect those not to be present to fail.
622 */
623 assert_se(unsetenv("VAR1") == 0);
624 assert_se(unsetenv("VAR2") == 0);
625 assert_se(unsetenv("VAR3") == 0);
626
627 r = run_tests(UNIT_FILE_USER, user_tests);
628 if (r != 0)
629 return r;
630
631 return run_tests(UNIT_FILE_SYSTEM, system_tests);
632 }