1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2014 Ronny Chevalier
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.
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.
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/>.
24 #include <sys/prctl.h>
25 #include <sys/types.h>
27 #include "capability-util.h"
28 #include "cpu-set-util.h"
29 #include "errno-list.h"
35 #include "path-util.h"
38 #include "seccomp-util.h"
40 #include "stat-util.h"
41 #include "test-helper.h"
44 #include "user-util.h"
48 typedef void (*test_function_t
)(Manager
*m
);
50 static void check(Manager
*m
, Unit
*unit
, int status_expected
, int code_expected
) {
51 Service
*service
= NULL
;
53 usec_t timeout
= 2 * USEC_PER_MINUTE
;
58 service
= SERVICE(unit
);
59 printf("%s\n", unit
->id
);
60 exec_context_dump(&service
->exec_context
, stdout
, "\t");
61 ts
= now(CLOCK_MONOTONIC
);
62 while (!IN_SET(service
->state
, SERVICE_DEAD
, SERVICE_FAILED
)) {
66 r
= sd_event_run(m
->event
, 100 * USEC_PER_MSEC
);
69 n
= now(CLOCK_MONOTONIC
);
70 if (ts
+ timeout
< n
) {
71 log_error("Test timeout when testing %s", unit
->id
);
75 exec_status_dump(&service
->main_exec_status
, stdout
, "\t");
76 assert_se(service
->main_exec_status
.status
== status_expected
);
77 assert_se(service
->main_exec_status
.code
== code_expected
);
80 static bool check_nobody_user_and_group(void) {
81 static int cache
= -1;
88 if (!synthesize_nobody())
91 p
= getpwnam(NOBODY_USER_NAME
);
93 !streq(p
->pw_name
, NOBODY_USER_NAME
) ||
94 p
->pw_uid
!= UID_NOBODY
||
95 p
->pw_gid
!= GID_NOBODY
)
98 p
= getpwuid(UID_NOBODY
);
100 !streq(p
->pw_name
, NOBODY_USER_NAME
) ||
101 p
->pw_uid
!= UID_NOBODY
||
102 p
->pw_gid
!= GID_NOBODY
)
105 g
= getgrnam(NOBODY_GROUP_NAME
);
107 !streq(g
->gr_name
, NOBODY_GROUP_NAME
) ||
108 g
->gr_gid
!= GID_NOBODY
)
111 g
= getgrgid(GID_NOBODY
);
113 !streq(g
->gr_name
, NOBODY_GROUP_NAME
) ||
114 g
->gr_gid
!= GID_NOBODY
)
125 static bool is_inaccessible_available(void) {
129 "/run/systemd/inaccessible/reg",
130 "/run/systemd/inaccessible/dir",
131 "/run/systemd/inaccessible/chr",
132 "/run/systemd/inaccessible/blk",
133 "/run/systemd/inaccessible/fifo",
134 "/run/systemd/inaccessible/sock"
136 if (access(p
, F_OK
) < 0)
143 static void test(Manager
*m
, const char *unit_name
, int status_expected
, int code_expected
) {
146 assert_se(unit_name
);
148 assert_se(manager_load_unit(m
, unit_name
, NULL
, NULL
, &unit
) >= 0);
149 assert_se(UNIT_VTABLE(unit
)->start(unit
) >= 0);
150 check(m
, unit
, status_expected
, code_expected
);
153 static void test_exec_bindpaths(Manager
*m
) {
154 assert_se(mkdir_p("/tmp/test-exec-bindpaths", 0755) >= 0);
155 assert_se(mkdir_p("/tmp/test-exec-bindreadonlypaths", 0755) >= 0);
157 test(m
, "exec-bindpaths.service", 0, CLD_EXITED
);
159 (void) rm_rf("/tmp/test-exec-bindpaths", REMOVE_ROOT
|REMOVE_PHYSICAL
);
160 (void) rm_rf("/tmp/test-exec-bindreadonlypaths", REMOVE_ROOT
|REMOVE_PHYSICAL
);
163 static void test_exec_cpuaffinity(Manager
*m
) {
164 _cleanup_cpu_free_ cpu_set_t
*c
= NULL
;
167 assert_se(c
= cpu_set_malloc(&n
));
168 assert_se(sched_getaffinity(0, CPU_ALLOC_SIZE(n
), c
) >= 0);
170 if (CPU_ISSET_S(0, CPU_ALLOC_SIZE(n
), c
) == 0) {
171 log_notice("Cannot use CPU 0, skipping %s", __func__
);
175 test(m
, "exec-cpuaffinity1.service", 0, CLD_EXITED
);
176 test(m
, "exec-cpuaffinity2.service", 0, CLD_EXITED
);
178 if (CPU_ISSET_S(1, CPU_ALLOC_SIZE(n
), c
) == 0 ||
179 CPU_ISSET_S(2, CPU_ALLOC_SIZE(n
), c
) == 0) {
180 log_notice("Cannot use CPU 1 or 2, skipping remaining tests in %s", __func__
);
184 test(m
, "exec-cpuaffinity3.service", 0, CLD_EXITED
);
187 static void test_exec_workingdirectory(Manager
*m
) {
188 assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
190 test(m
, "exec-workingdirectory.service", 0, CLD_EXITED
);
192 (void) rm_rf("/tmp/test-exec_workingdirectory", REMOVE_ROOT
|REMOVE_PHYSICAL
);
195 static void test_exec_personality(Manager
*m
) {
196 #if defined(__x86_64__)
197 test(m
, "exec-personality-x86-64.service", 0, CLD_EXITED
);
199 #elif defined(__s390__)
200 test(m
, "exec-personality-s390.service", 0, CLD_EXITED
);
202 #elif defined(__powerpc64__)
203 # if __BYTE_ORDER == __BIG_ENDIAN
204 test(m
, "exec-personality-ppc64.service", 0, CLD_EXITED
);
206 test(m
, "exec-personality-ppc64le.service", 0, CLD_EXITED
);
209 #elif defined(__aarch64__)
210 test(m
, "exec-personality-aarch64.service", 0, CLD_EXITED
);
212 #elif defined(__i386__)
213 test(m
, "exec-personality-x86.service", 0, CLD_EXITED
);
215 log_notice("Unknown personality, skipping %s", __func__
);
219 static void test_exec_ignoresigpipe(Manager
*m
) {
220 test(m
, "exec-ignoresigpipe-yes.service", 0, CLD_EXITED
);
221 test(m
, "exec-ignoresigpipe-no.service", SIGPIPE
, CLD_KILLED
);
224 static void test_exec_privatetmp(Manager
*m
) {
225 assert_se(touch("/tmp/test-exec_privatetmp") >= 0);
227 test(m
, "exec-privatetmp-yes.service", 0, CLD_EXITED
);
228 test(m
, "exec-privatetmp-no.service", 0, CLD_EXITED
);
230 unlink("/tmp/test-exec_privatetmp");
233 static void test_exec_privatedevices(Manager
*m
) {
236 if (detect_container() > 0) {
237 log_notice("Testing in container, skipping %s", __func__
);
240 if (!is_inaccessible_available()) {
241 log_notice("Testing without inaccessible, skipping %s", __func__
);
245 test(m
, "exec-privatedevices-yes.service", 0, CLD_EXITED
);
246 test(m
, "exec-privatedevices-no.service", 0, CLD_EXITED
);
248 /* We use capsh to test if the capabilities are
249 * properly set, so be sure that it exists */
250 r
= find_binary("capsh", NULL
);
252 log_notice_errno(r
, "Could not find capsh binary, skipping remaining tests in %s: %m", __func__
);
256 test(m
, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED
);
257 test(m
, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED
);
258 test(m
, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED
);
259 test(m
, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED
);
262 static void test_exec_protectkernelmodules(Manager
*m
) {
265 if (detect_container() > 0) {
266 log_notice("Testing in container, skipping %s", __func__
);
269 if (!is_inaccessible_available()) {
270 log_notice("Testing without inaccessible, skipping %s", __func__
);
274 r
= find_binary("capsh", NULL
);
276 log_notice_errno(r
, "Skipping %s, could not find capsh binary: %m", __func__
);
280 test(m
, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED
);
281 test(m
, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED
);
282 test(m
, "exec-protectkernelmodules-yes-mount-propagation.service", 0, CLD_EXITED
);
285 static void test_exec_readonlypaths(Manager
*m
) {
287 test(m
, "exec-readonlypaths-simple.service", 0, CLD_EXITED
);
289 if (path_is_read_only_fs("/var") > 0) {
290 log_notice("Directory /var is readonly, skipping remaining tests in %s", __func__
);
294 test(m
, "exec-readonlypaths.service", 0, CLD_EXITED
);
295 test(m
, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED
);
296 test(m
, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED
);
299 static void test_exec_readwritepaths(Manager
*m
) {
301 if (path_is_read_only_fs("/") > 0) {
302 log_notice("Root directory is readonly, skipping %s", __func__
);
306 test(m
, "exec-readwritepaths-mount-propagation.service", 0, CLD_EXITED
);
309 static void test_exec_inaccessiblepaths(Manager
*m
) {
311 if (!is_inaccessible_available()) {
312 log_notice("Testing without inaccessible, skipping %s", __func__
);
316 test(m
, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED
);
318 if (path_is_read_only_fs("/") > 0) {
319 log_notice("Root directory is readonly, skipping remaining tests in %s", __func__
);
323 test(m
, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED
);
326 static void test_exec_temporaryfilesystem(Manager
*m
) {
328 test(m
, "exec-temporaryfilesystem-options.service", 0, CLD_EXITED
);
329 test(m
, "exec-temporaryfilesystem-ro.service", 0, CLD_EXITED
);
330 test(m
, "exec-temporaryfilesystem-rw.service", 0, CLD_EXITED
);
331 test(m
, "exec-temporaryfilesystem-usr.service", 0, CLD_EXITED
);
334 static void test_exec_systemcallfilter(Manager
*m
) {
336 if (!is_seccomp_available()) {
337 log_notice("Seccomp not available, skipping %s", __func__
);
341 test(m
, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED
);
342 test(m
, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED
);
343 test(m
, "exec-systemcallfilter-failing.service", SIGSYS
, CLD_KILLED
);
344 test(m
, "exec-systemcallfilter-failing2.service", SIGSYS
, CLD_KILLED
);
345 test(m
, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED
);
346 test(m
, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED
);
350 static void test_exec_systemcallerrornumber(Manager
*m
) {
352 if (!is_seccomp_available()) {
353 log_notice("Seccomp not available, skipping %s", __func__
);
357 test(m
, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED
);
358 test(m
, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED
);
362 static void test_exec_restrictnamespaces(Manager
*m
) {
364 if (!is_seccomp_available()) {
365 log_notice("Seccomp not available, skipping %s", __func__
);
369 test(m
, "exec-restrictnamespaces-no.service", 0, CLD_EXITED
);
370 test(m
, "exec-restrictnamespaces-yes.service", 1, CLD_EXITED
);
371 test(m
, "exec-restrictnamespaces-mnt.service", 0, CLD_EXITED
);
372 test(m
, "exec-restrictnamespaces-mnt-blacklist.service", 1, CLD_EXITED
);
376 static void test_exec_systemcallfilter_system(Manager
*m
) {
378 if (!is_seccomp_available()) {
379 log_notice("Seccomp not available, skipping %s", __func__
);
383 test(m
, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED
);
385 if (!check_nobody_user_and_group()) {
386 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__
);
390 if (!STR_IN_SET(NOBODY_USER_NAME
, "nobody", "nfsnobody")) {
391 log_notice("Unsupported nobody user name '%s', skipping remaining tests in %s", NOBODY_USER_NAME
, __func__
);
395 test(m
, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME
".service", 0, CLD_EXITED
);
399 static void test_exec_user(Manager
*m
) {
400 test(m
, "exec-user.service", 0, CLD_EXITED
);
402 if (!check_nobody_user_and_group()) {
403 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__
);
407 if (!STR_IN_SET(NOBODY_USER_NAME
, "nobody", "nfsnobody")) {
408 log_notice("Unsupported nobody user name '%s', skipping remaining tests in %s", NOBODY_USER_NAME
, __func__
);
412 test(m
, "exec-user-" NOBODY_USER_NAME
".service", 0, CLD_EXITED
);
415 static void test_exec_group(Manager
*m
) {
416 test(m
, "exec-group.service", 0, CLD_EXITED
);
418 if (!check_nobody_user_and_group()) {
419 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__
);
423 if (!STR_IN_SET(NOBODY_GROUP_NAME
, "nobody", "nfsnobody", "nogroup")) {
424 log_notice("Unsupported nobody group name '%s', skipping remaining tests in %s", NOBODY_GROUP_NAME
, __func__
);
428 test(m
, "exec-group-" NOBODY_GROUP_NAME
".service", 0, CLD_EXITED
);
431 static void test_exec_supplementarygroups(Manager
*m
) {
432 test(m
, "exec-supplementarygroups.service", 0, CLD_EXITED
);
433 test(m
, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED
);
434 test(m
, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED
);
435 test(m
, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED
);
436 test(m
, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED
);
437 test(m
, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED
);
440 static void test_exec_dynamicuser(Manager
*m
) {
441 test(m
, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED
);
442 test(m
, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED
);
443 test(m
, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED
);
444 test(m
, "exec-dynamicuser-statedir.service", 0, CLD_EXITED
);
446 test(m
, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED
);
447 test(m
, "exec-dynamicuser-statedir-migrate-step2.service", 0, CLD_EXITED
);
448 (void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT
|REMOVE_PHYSICAL
);
449 (void) rm_rf("/var/lib/test-dynamicuser-migrate2", REMOVE_ROOT
|REMOVE_PHYSICAL
);
450 (void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT
|REMOVE_PHYSICAL
);
451 (void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT
|REMOVE_PHYSICAL
);
454 static void test_exec_environment(Manager
*m
) {
455 test(m
, "exec-environment.service", 0, CLD_EXITED
);
456 test(m
, "exec-environment-multiple.service", 0, CLD_EXITED
);
457 test(m
, "exec-environment-empty.service", 0, CLD_EXITED
);
460 static void test_exec_environmentfile(Manager
*m
) {
461 static const char e
[] =
462 "VAR1='word1 word2'\n"
468 "line without an equal\n"
469 "VAR3='$word 5 6'\n";
472 r
= write_string_file("/tmp/test-exec_environmentfile.conf", e
, WRITE_STRING_FILE_CREATE
);
475 test(m
, "exec-environmentfile.service", 0, CLD_EXITED
);
477 (void) unlink("/tmp/test-exec_environmentfile.conf");
480 static void test_exec_passenvironment(Manager
*m
) {
481 /* test-execute runs under MANAGER_USER which, by default, forwards all
482 * variables present in the environment, but only those that are
483 * present _at the time it is created_!
485 * So these PassEnvironment checks are still expected to work, since we
486 * are ensuring the variables are not present at manager creation (they
487 * are unset explicitly in main) and are only set here.
489 * This is still a good approximation of how a test for MANAGER_SYSTEM
492 assert_se(setenv("VAR1", "word1 word2", 1) == 0);
493 assert_se(setenv("VAR2", "word3", 1) == 0);
494 assert_se(setenv("VAR3", "$word 5 6", 1) == 0);
495 test(m
, "exec-passenvironment.service", 0, CLD_EXITED
);
496 test(m
, "exec-passenvironment-repeated.service", 0, CLD_EXITED
);
497 test(m
, "exec-passenvironment-empty.service", 0, CLD_EXITED
);
498 assert_se(unsetenv("VAR1") == 0);
499 assert_se(unsetenv("VAR2") == 0);
500 assert_se(unsetenv("VAR3") == 0);
501 test(m
, "exec-passenvironment-absent.service", 0, CLD_EXITED
);
504 static void test_exec_umask(Manager
*m
) {
505 test(m
, "exec-umask-default.service", 0, CLD_EXITED
);
506 test(m
, "exec-umask-0177.service", 0, CLD_EXITED
);
509 static void test_exec_runtimedirectory(Manager
*m
) {
510 test(m
, "exec-runtimedirectory.service", 0, CLD_EXITED
);
511 test(m
, "exec-runtimedirectory-mode.service", 0, CLD_EXITED
);
512 test(m
, "exec-runtimedirectory-owner.service", 0, CLD_EXITED
);
514 if (!check_nobody_user_and_group()) {
515 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__
);
519 if (!STR_IN_SET(NOBODY_GROUP_NAME
, "nobody", "nfsnobody", "nogroup")) {
520 log_notice("Unsupported nobody group name '%s', skipping remaining tests in %s", NOBODY_GROUP_NAME
, __func__
);
524 test(m
, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME
".service", 0, CLD_EXITED
);
527 static void test_exec_capabilityboundingset(Manager
*m
) {
530 r
= find_binary("capsh", NULL
);
532 log_notice_errno(r
, "Skipping %s, could not find capsh binary: %m", __func__
);
536 if (have_effective_cap(CAP_CHOWN
) <= 0 ||
537 have_effective_cap(CAP_FOWNER
) <= 0 ||
538 have_effective_cap(CAP_KILL
) <= 0) {
539 log_notice("Skipping %s, this process does not have enough capabilities", __func__
);
543 test(m
, "exec-capabilityboundingset-simple.service", 0, CLD_EXITED
);
544 test(m
, "exec-capabilityboundingset-reset.service", 0, CLD_EXITED
);
545 test(m
, "exec-capabilityboundingset-merge.service", 0, CLD_EXITED
);
546 test(m
, "exec-capabilityboundingset-invert.service", 0, CLD_EXITED
);
549 static void test_exec_ambientcapabilities(Manager
*m
) {
552 /* Check if the kernel has support for ambient capabilities. Run
553 * the tests only if that's the case. Clearing all ambient
554 * capabilities is fine, since we are expecting them to be unset
555 * in the first place for the tests. */
556 r
= prctl(PR_CAP_AMBIENT
, PR_CAP_AMBIENT_CLEAR_ALL
, 0, 0, 0);
557 if (r
< 0 && IN_SET(errno
, EINVAL
, EOPNOTSUPP
, ENOSYS
)) {
558 log_notice("Skipping %s, the kernel does not support ambient capabilities", __func__
);
562 if (have_effective_cap(CAP_CHOWN
) <= 0 ||
563 have_effective_cap(CAP_NET_RAW
) <= 0) {
564 log_notice("Skipping %s, this process does not have enough capabilities", __func__
);
568 test(m
, "exec-ambientcapabilities.service", 0, CLD_EXITED
);
569 test(m
, "exec-ambientcapabilities-merge.service", 0, CLD_EXITED
);
571 if (!check_nobody_user_and_group()) {
572 log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__
);
576 if (!STR_IN_SET(NOBODY_USER_NAME
, "nobody", "nfsnobody")) {
577 log_notice("Unsupported nobody user name '%s', skipping remaining tests in %s", NOBODY_USER_NAME
, __func__
);
581 test(m
, "exec-ambientcapabilities-" NOBODY_USER_NAME
".service", 0, CLD_EXITED
);
582 test(m
, "exec-ambientcapabilities-merge-" NOBODY_USER_NAME
".service", 0, CLD_EXITED
);
585 static void test_exec_privatenetwork(Manager
*m
) {
588 r
= find_binary("ip", NULL
);
590 log_notice_errno(r
, "Skipping %s, could not find ip binary: %m", __func__
);
594 test(m
, "exec-privatenetwork-yes.service", 0, CLD_EXITED
);
597 static void test_exec_oomscoreadjust(Manager
*m
) {
598 test(m
, "exec-oomscoreadjust-positive.service", 0, CLD_EXITED
);
599 test(m
, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED
);
602 static void test_exec_ioschedulingclass(Manager
*m
) {
603 test(m
, "exec-ioschedulingclass-none.service", 0, CLD_EXITED
);
604 test(m
, "exec-ioschedulingclass-idle.service", 0, CLD_EXITED
);
605 test(m
, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED
);
606 test(m
, "exec-ioschedulingclass-best-effort.service", 0, CLD_EXITED
);
609 static void test_exec_unsetenvironment(Manager
*m
) {
610 test(m
, "exec-unsetenvironment.service", 0, CLD_EXITED
);
613 static void test_exec_specifier(Manager
*m
) {
614 test(m
, "exec-specifier.service", 0, CLD_EXITED
);
615 test(m
, "exec-specifier@foo-bar.service", 0, CLD_EXITED
);
616 test(m
, "exec-specifier-interpolation.service", 0, CLD_EXITED
);
619 static void test_exec_standardinput(Manager
*m
) {
620 test(m
, "exec-standardinput-data.service", 0, CLD_EXITED
);
621 test(m
, "exec-standardinput-file.service", 0, CLD_EXITED
);
624 static int run_tests(UnitFileScope scope
, const test_function_t
*tests
) {
625 const test_function_t
*test
= NULL
;
626 _cleanup_(manager_freep
) Manager
*m
= NULL
;
631 r
= manager_new(scope
, MANAGER_TEST_RUN_BASIC
, &m
);
632 if (MANAGER_SKIP_TEST(r
)) {
633 log_notice_errno(r
, "Skipping test: manager_new: %m");
634 return EXIT_TEST_SKIP
;
637 assert_se(manager_startup(m
, NULL
, NULL
) >= 0);
639 for (test
= tests
; test
&& *test
; test
++)
645 int main(int argc
, char *argv
[]) {
646 _cleanup_(rm_rf_physical_and_freep
) char *runtime_dir
= NULL
;
647 static const test_function_t user_tests
[] = {
648 test_exec_ambientcapabilities
,
650 test_exec_capabilityboundingset
,
651 test_exec_cpuaffinity
,
652 test_exec_environment
,
653 test_exec_environmentfile
,
655 test_exec_ignoresigpipe
,
656 test_exec_inaccessiblepaths
,
657 test_exec_ioschedulingclass
,
658 test_exec_oomscoreadjust
,
659 test_exec_passenvironment
,
660 test_exec_personality
,
661 test_exec_privatedevices
,
662 test_exec_privatenetwork
,
663 test_exec_privatetmp
,
664 test_exec_protectkernelmodules
,
665 test_exec_readonlypaths
,
666 test_exec_readwritepaths
,
667 test_exec_restrictnamespaces
,
668 test_exec_runtimedirectory
,
669 test_exec_standardinput
,
670 test_exec_supplementarygroups
,
671 test_exec_systemcallerrornumber
,
672 test_exec_systemcallfilter
,
673 test_exec_temporaryfilesystem
,
675 test_exec_unsetenvironment
,
677 test_exec_workingdirectory
,
680 static const test_function_t system_tests
[] = {
681 test_exec_dynamicuser
,
683 test_exec_systemcallfilter_system
,
688 log_set_max_level(LOG_DEBUG
);
689 log_parse_environment();
692 (void) unsetenv("USER");
693 (void) unsetenv("LOGNAME");
695 /* It is needed otherwise cgroup creation fails */
697 puts("Skipping test: not root");
698 return EXIT_TEST_SKIP
;
701 r
= enter_cgroup_subroot();
702 if (r
== -ENOMEDIUM
) {
703 puts("Skipping test: cgroupfs not available");
704 return EXIT_TEST_SKIP
;
707 assert_se(runtime_dir
= setup_fake_runtime_dir());
708 assert_se(set_unit_path(get_testdata_dir("/test-execute")) >= 0);
710 /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
711 * cases, otherwise (and if they are present in the environment),
712 * `manager_default_environment` will copy them into the default
713 * environment which is passed to each created job, which will make the
714 * tests that expect those not to be present to fail.
716 assert_se(unsetenv("VAR1") == 0);
717 assert_se(unsetenv("VAR2") == 0);
718 assert_se(unsetenv("VAR3") == 0);
720 r
= run_tests(UNIT_FILE_USER
, user_tests
);
724 return run_tests(UNIT_FILE_SYSTEM
, system_tests
);