889 lines
40 KiB
Diff
889 lines
40 KiB
Diff
|
From bdde465ad1df52cb9b9fbaab37d5d7541601d774 Mon Sep 17 00:00:00 2001
|
||
|
From: Yu Watanabe <watanabe.yu+github@gmail.com>
|
||
|
Date: Fri, 3 Feb 2023 12:28:31 +0900
|
||
|
Subject: [PATCH] test-execute: drop capabilities when testing with user
|
||
|
manager
|
||
|
|
||
|
Before this, tests are split into two categories, system and user, but
|
||
|
both are running in fully privileged environment. Hence, unprivileged
|
||
|
user scope was mostly not covered by the test.
|
||
|
|
||
|
Let's run all tests in both system and user scopes, and drop capabilities
|
||
|
when Manager is running in user scope.
|
||
|
|
||
|
This also makes the host environment protected more from the test run.
|
||
|
|
||
|
(cherry picked from commit 4e032f654b94c2544ccf937209303766dfa66c24)
|
||
|
|
||
|
Related: RHEL-27512
|
||
|
---
|
||
|
src/test/test-execute.c | 351 +++++++++++-------
|
||
|
...dynamicuser-statedir-migrate-step1.service | 16 +-
|
||
|
...dynamicuser-statedir-migrate-step2.service | 32 +-
|
||
|
.../exec-dynamicuser-statedir.service | 122 +++---
|
||
|
.../exec-privatenetwork-yes.service | 1 +
|
||
|
.../exec-specifier-system.service | 11 +
|
||
|
test/test-execute/exec-specifier-user.service | 11 +
|
||
|
test/test-execute/exec-specifier.service | 5 -
|
||
|
test/test-execute/exec-specifier@.service | 5 -
|
||
|
9 files changed, 333 insertions(+), 221 deletions(-)
|
||
|
create mode 100644 test/test-execute/exec-specifier-system.service
|
||
|
create mode 100644 test/test-execute/exec-specifier-user.service
|
||
|
|
||
|
diff --git a/src/test/test-execute.c b/src/test/test-execute.c
|
||
|
index ce3489d708..665ae8a833 100644
|
||
|
--- a/src/test/test-execute.c
|
||
|
+++ b/src/test/test-execute.c
|
||
|
@@ -1,6 +1,7 @@
|
||
|
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||
|
|
||
|
#include <stdio.h>
|
||
|
+#include <sys/mount.h>
|
||
|
#include <sys/prctl.h>
|
||
|
#include <sys/types.h>
|
||
|
|
||
|
@@ -18,6 +19,7 @@
|
||
|
#include "manager.h"
|
||
|
#include "missing_prctl.h"
|
||
|
#include "mkdir.h"
|
||
|
+#include "mount-util.h"
|
||
|
#include "path-util.h"
|
||
|
#include "process-util.h"
|
||
|
#include "rm-rf.h"
|
||
|
@@ -35,6 +37,8 @@
|
||
|
#include "util.h"
|
||
|
#include "virt.h"
|
||
|
|
||
|
+#define PRIVATE_UNIT_DIR "/run/test-execute-unit-dir"
|
||
|
+
|
||
|
static char *user_runtime_unit_dir = NULL;
|
||
|
static bool can_unshare;
|
||
|
|
||
|
@@ -414,7 +418,7 @@ static void test_exec_privatedevices(Manager *m) {
|
||
|
test(m, "exec-privatedevices-yes.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
test(m, "exec-privatedevices-no.service", 0, CLD_EXITED);
|
||
|
test(m, "exec-privatedevices-disabled-by-prefix.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
- test(m, "exec-privatedevices-yes-with-group.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
+ test(m, "exec-privatedevices-yes-with-group.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_FAILURE : EXIT_GROUP, CLD_EXITED);
|
||
|
|
||
|
/* We use capsh to test if the capabilities are
|
||
|
* properly set, so be sure that it exists */
|
||
|
@@ -425,9 +429,9 @@ static void test_exec_privatedevices(Manager *m) {
|
||
|
}
|
||
|
|
||
|
test(m, "exec-privatedevices-yes-capability-mknod.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-privatedevices-no-capability-mknod.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-privatedevices-no-capability-mknod.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
test(m, "exec-privatedevices-yes-capability-sys-rawio.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-privatedevices-no-capability-sys-rawio.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-privatedevices-no-capability-sys-rawio.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_protecthome(Manager *m) {
|
||
|
@@ -457,7 +461,7 @@ static void test_exec_protectkernelmodules(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-protectkernelmodules-no-capabilities.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-protectkernelmodules-no-capabilities.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
test(m, "exec-protectkernelmodules-yes-capabilities.service", 0, CLD_EXITED);
|
||
|
test(m, "exec-protectkernelmodules-yes-mount-propagation.service", can_unshare ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
}
|
||
|
@@ -778,7 +782,7 @@ static void test_exec_systemcallfilter_system(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-systemcallfilter-system-user.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-systemcallfilter-system-user.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
|
||
|
if (!check_nobody_user_and_group()) {
|
||
|
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||
|
@@ -790,12 +794,12 @@ static void test_exec_systemcallfilter_system(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-systemcallfilter-system-user-" NOBODY_USER_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
static void test_exec_user(Manager *m) {
|
||
|
- test(m, "exec-user.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-user.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
|
||
|
if (!check_nobody_user_and_group()) {
|
||
|
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||
|
@@ -807,11 +811,11 @@ static void test_exec_user(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-user-" NOBODY_USER_NAME ".service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-user-" NOBODY_USER_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_group(Manager *m) {
|
||
|
- test(m, "exec-group.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-group.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
|
||
|
if (!check_nobody_user_and_group()) {
|
||
|
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||
|
@@ -823,16 +827,17 @@ static void test_exec_group(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-group-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-group-" NOBODY_GROUP_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_supplementarygroups(Manager *m) {
|
||
|
- test(m, "exec-supplementarygroups.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-supplementarygroups-single-group.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-supplementarygroups-single-group-user.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-supplementarygroups-multiple-groups-withgid.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-supplementarygroups-multiple-groups-withuid.service", 0, CLD_EXITED);
|
||
|
+ int status = MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP;
|
||
|
+ test(m, "exec-supplementarygroups.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-supplementarygroups-single-group.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-supplementarygroups-single-group-user.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-supplementarygroups-multiple-groups-default-group-user.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-supplementarygroups-multiple-groups-withgid.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-supplementarygroups-multiple-groups-withuid.service", status, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static char* private_directory_bad(Manager *m) {
|
||
|
@@ -864,14 +869,16 @@ static void test_exec_dynamicuser(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-dynamicuser-fixeduser.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
+ int status = can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NAMESPACE : EXIT_GROUP;
|
||
|
+
|
||
|
+ test(m, "exec-dynamicuser-fixeduser.service", status, CLD_EXITED);
|
||
|
if (check_user_has_group_with_same_name("adm"))
|
||
|
- test(m, "exec-dynamicuser-fixeduser-adm.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-fixeduser-adm.service", status, CLD_EXITED);
|
||
|
if (check_user_has_group_with_same_name("games"))
|
||
|
- test(m, "exec-dynamicuser-fixeduser-games.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
- test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
- test(m, "exec-dynamicuser-supplementarygroups.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
- test(m, "exec-dynamicuser-statedir.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-fixeduser-games.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-supplementarygroups.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-statedir.service", status, CLD_EXITED);
|
||
|
|
||
|
(void) rm_rf("/var/lib/quux", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
(void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
@@ -883,7 +890,7 @@ static void test_exec_dynamicuser(Manager *m) {
|
||
|
(void) rm_rf("/var/lib/private/waldo", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
|
||
|
test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-dynamicuser-statedir-migrate-step2.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-statedir-migrate-step2.service", status, CLD_EXITED);
|
||
|
test(m, "exec-dynamicuser-statedir-migrate-step1.service", 0, CLD_EXITED);
|
||
|
|
||
|
(void) rm_rf("/var/lib/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
@@ -891,9 +898,9 @@ static void test_exec_dynamicuser(Manager *m) {
|
||
|
(void) rm_rf("/var/lib/private/test-dynamicuser-migrate", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
(void) rm_rf("/var/lib/private/test-dynamicuser-migrate2", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
|
||
|
- test(m, "exec-dynamicuser-runtimedirectory1.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
- test(m, "exec-dynamicuser-runtimedirectory2.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
- test(m, "exec-dynamicuser-runtimedirectory3.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-runtimedirectory1.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-runtimedirectory2.service", status, CLD_EXITED);
|
||
|
+ test(m, "exec-dynamicuser-runtimedirectory3.service", status, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_environment(Manager *m) {
|
||
|
@@ -959,9 +966,12 @@ static void test_exec_umask(Manager *m) {
|
||
|
}
|
||
|
|
||
|
static void test_exec_runtimedirectory(Manager *m) {
|
||
|
+ (void) rm_rf("/run/test-exec_runtimedirectory2", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
test(m, "exec-runtimedirectory.service", 0, CLD_EXITED);
|
||
|
+ (void) rm_rf("/run/test-exec_runtimedirectory2", REMOVE_ROOT|REMOVE_PHYSICAL);
|
||
|
+
|
||
|
test(m, "exec-runtimedirectory-mode.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-runtimedirectory-owner.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-runtimedirectory-owner.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
|
||
|
if (!check_nobody_user_and_group()) {
|
||
|
log_notice("nobody user/group is not synthesized or may conflict to other entries, skipping remaining tests in %s", __func__);
|
||
|
@@ -973,7 +983,7 @@ static void test_exec_runtimedirectory(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-runtimedirectory-owner-" NOBODY_GROUP_NAME ".service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_GROUP, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_capabilityboundingset(Manager *m) {
|
||
|
@@ -1047,7 +1057,7 @@ static void test_exec_privatenetwork(Manager *m) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
- test(m, "exec-privatenetwork-yes.service", can_unshare ? 0 : EXIT_NETWORK, CLD_EXITED);
|
||
|
+ test(m, "exec-privatenetwork-yes.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NETWORK : EXIT_FAILURE, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_oomscoreadjust(Manager *m) {
|
||
|
@@ -1057,7 +1067,7 @@ static void test_exec_oomscoreadjust(Manager *m) {
|
||
|
log_notice("Testing in container, skipping remaining tests in %s", __func__);
|
||
|
return;
|
||
|
}
|
||
|
- test(m, "exec-oomscoreadjust-negative.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-oomscoreadjust-negative.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_FAILURE, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_ioschedulingclass(Manager *m) {
|
||
|
@@ -1069,7 +1079,7 @@ static void test_exec_ioschedulingclass(Manager *m) {
|
||
|
log_notice("Testing in container, skipping remaining tests in %s", __func__);
|
||
|
return;
|
||
|
}
|
||
|
- test(m, "exec-ioschedulingclass-realtime.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-ioschedulingclass-realtime.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_IOPRIO, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_unsetenvironment(Manager *m) {
|
||
|
@@ -1078,9 +1088,13 @@ static void test_exec_unsetenvironment(Manager *m) {
|
||
|
|
||
|
static void test_exec_specifier(Manager *m) {
|
||
|
test(m, "exec-specifier.service", 0, CLD_EXITED);
|
||
|
+ if (MANAGER_IS_SYSTEM(m))
|
||
|
+ test(m, "exec-specifier-system.service", 0, CLD_EXITED);
|
||
|
+ else
|
||
|
+ test(m, "exec-specifier-user.service", 0, CLD_EXITED);
|
||
|
test(m, "exec-specifier@foo-bar.service", 0, CLD_EXITED);
|
||
|
test(m, "exec-specifier-interpolation.service", 0, CLD_EXITED);
|
||
|
- test(m, "exec-specifier-credentials-dir.service", 0, CLD_EXITED);
|
||
|
+ test(m, "exec-specifier-credentials-dir.service", MANAGER_IS_SYSTEM(m) ? 0 : EXIT_CREDENTIALS, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
static void test_exec_standardinput(Manager *m) {
|
||
|
@@ -1113,7 +1127,7 @@ static void test_exec_umask_namespace(Manager *m) {
|
||
|
log_notice("Testing without inaccessible, skipping %s", __func__);
|
||
|
return;
|
||
|
}
|
||
|
- test(m, "exec-umask-namespace.service", can_unshare ? 0 : EXIT_NAMESPACE, CLD_EXITED);
|
||
|
+ test(m, "exec-umask-namespace.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_NAMESPACE : EXIT_GROUP, CLD_EXITED);
|
||
|
}
|
||
|
|
||
|
typedef struct test_entry {
|
||
|
@@ -1123,40 +1137,27 @@ typedef struct test_entry {
|
||
|
|
||
|
#define entry(x) {x, #x}
|
||
|
|
||
|
-static int run_tests(LookupScope scope, const test_entry tests[], char **patterns) {
|
||
|
+static void run_tests(LookupScope scope, char **patterns) {
|
||
|
+ _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
||
|
+ _cleanup_free_ char *unit_paths = NULL;
|
||
|
_cleanup_(manager_freep) Manager *m = NULL;
|
||
|
int r;
|
||
|
|
||
|
- assert_se(tests);
|
||
|
-
|
||
|
- r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m);
|
||
|
- m->default_std_output = EXEC_OUTPUT_NULL; /* don't rely on host journald */
|
||
|
- if (manager_errno_skip_test(r))
|
||
|
- return log_tests_skipped_errno(r, "manager_new");
|
||
|
- assert_se(r >= 0);
|
||
|
- assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||
|
-
|
||
|
- for (const test_entry *test = tests; test->f; test++)
|
||
|
- if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
|
||
|
- test->f(m);
|
||
|
- else
|
||
|
- log_info("Skipping %s because it does not match any pattern.", test->name);
|
||
|
-
|
||
|
- return 0;
|
||
|
-}
|
||
|
-
|
||
|
-int main(int argc, char *argv[]) {
|
||
|
- _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL;
|
||
|
-
|
||
|
- static const test_entry user_tests[] = {
|
||
|
+ static const test_entry tests[] = {
|
||
|
entry(test_exec_basic),
|
||
|
entry(test_exec_ambientcapabilities),
|
||
|
entry(test_exec_bindpaths),
|
||
|
entry(test_exec_capabilityboundingset),
|
||
|
entry(test_exec_condition),
|
||
|
entry(test_exec_cpuaffinity),
|
||
|
+ entry(test_exec_dynamicuser),
|
||
|
entry(test_exec_environment),
|
||
|
entry(test_exec_environmentfile),
|
||
|
+ entry(test_exec_execsearchpath),
|
||
|
+ entry(test_exec_execsearchpath_environment),
|
||
|
+ entry(test_exec_execsearchpath_environment_files),
|
||
|
+ entry(test_exec_execsearchpath_passenvironment),
|
||
|
+ entry(test_exec_execsearchpath_specifier),
|
||
|
entry(test_exec_group),
|
||
|
entry(test_exec_ignoresigpipe),
|
||
|
entry(test_exec_inaccessiblepaths),
|
||
|
@@ -1175,6 +1176,7 @@ int main(int argc, char *argv[]) {
|
||
|
entry(test_exec_readwritepaths),
|
||
|
entry(test_exec_restrictnamespaces),
|
||
|
entry(test_exec_runtimedirectory),
|
||
|
+ entry(test_exec_specifier),
|
||
|
entry(test_exec_standardinput),
|
||
|
entry(test_exec_standardoutput),
|
||
|
entry(test_exec_standardoutput_append),
|
||
|
@@ -1182,35 +1184,15 @@ int main(int argc, char *argv[]) {
|
||
|
entry(test_exec_supplementarygroups),
|
||
|
entry(test_exec_systemcallerrornumber),
|
||
|
entry(test_exec_systemcallfilter),
|
||
|
+ entry(test_exec_systemcallfilter_system),
|
||
|
entry(test_exec_temporaryfilesystem),
|
||
|
entry(test_exec_umask),
|
||
|
+ entry(test_exec_umask_namespace),
|
||
|
entry(test_exec_unsetenvironment),
|
||
|
entry(test_exec_user),
|
||
|
entry(test_exec_workingdirectory),
|
||
|
- entry(test_exec_execsearchpath),
|
||
|
- entry(test_exec_execsearchpath_environment),
|
||
|
- entry(test_exec_execsearchpath_environment_files),
|
||
|
- entry(test_exec_execsearchpath_passenvironment),
|
||
|
- {},
|
||
|
- };
|
||
|
- static const test_entry system_tests[] = {
|
||
|
- entry(test_exec_dynamicuser),
|
||
|
- entry(test_exec_specifier),
|
||
|
- entry(test_exec_execsearchpath_specifier),
|
||
|
- entry(test_exec_systemcallfilter_system),
|
||
|
- entry(test_exec_umask_namespace),
|
||
|
{},
|
||
|
};
|
||
|
- int r;
|
||
|
-
|
||
|
- test_setup_logging(LOG_DEBUG);
|
||
|
-
|
||
|
-#if HAS_FEATURE_ADDRESS_SANITIZER
|
||
|
- if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions")) {
|
||
|
- log_notice("Running on Travis CI/GH Actions under ASan, skipping, see https://github.com/systemd/systemd/issues/10696");
|
||
|
- return EXIT_TEST_SKIP;
|
||
|
- }
|
||
|
-#endif
|
||
|
|
||
|
assert_se(unsetenv("USER") == 0);
|
||
|
assert_se(unsetenv("LOGNAME") == 0);
|
||
|
@@ -1218,68 +1200,185 @@ int main(int argc, char *argv[]) {
|
||
|
assert_se(unsetenv("HOME") == 0);
|
||
|
assert_se(unsetenv("TMPDIR") == 0);
|
||
|
|
||
|
- can_unshare = have_namespaces();
|
||
|
-
|
||
|
- /* It is needed otherwise cgroup creation fails */
|
||
|
- if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
|
||
|
- return log_tests_skipped("not privileged");
|
||
|
-
|
||
|
- r = enter_cgroup_subroot(NULL);
|
||
|
- if (r == -ENOMEDIUM)
|
||
|
- return log_tests_skipped("cgroupfs not available");
|
||
|
-
|
||
|
- if (path_is_read_only_fs("/sys") > 0)
|
||
|
- return log_tests_skipped("/sys is mounted read-only");
|
||
|
+ /* Unset VARx, especially, VAR1, VAR2 and VAR3, which are used in the PassEnvironment test cases,
|
||
|
+ * otherwise (and if they are present in the environment), `manager_default_environment` will copy
|
||
|
+ * them into the default environment which is passed to each created job, which will make the tests
|
||
|
+ * that expect those not to be present to fail. */
|
||
|
+ assert_se(unsetenv("VAR1") == 0);
|
||
|
+ assert_se(unsetenv("VAR2") == 0);
|
||
|
+ assert_se(unsetenv("VAR3") == 0);
|
||
|
+ assert_se(unsetenv("VAR4") == 0);
|
||
|
+ assert_se(unsetenv("VAR5") == 0);
|
||
|
|
||
|
- _cleanup_free_ char *unit_dir = NULL, *unit_paths = NULL;
|
||
|
- assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
|
||
|
assert_se(runtime_dir = setup_fake_runtime_dir());
|
||
|
assert_se(user_runtime_unit_dir = path_join(runtime_dir, "systemd/user"));
|
||
|
- assert_se(unit_paths = strjoin(unit_dir, ":", user_runtime_unit_dir));
|
||
|
+ assert_se(unit_paths = strjoin(PRIVATE_UNIT_DIR, ":", user_runtime_unit_dir));
|
||
|
assert_se(set_unit_path(unit_paths) >= 0);
|
||
|
|
||
|
- /* Unset VAR1, VAR2 and VAR3 which are used in the PassEnvironment test
|
||
|
- * cases, otherwise (and if they are present in the environment),
|
||
|
- * `manager_default_environment` will copy them into the default
|
||
|
- * environment which is passed to each created job, which will make the
|
||
|
- * tests that expect those not to be present to fail.
|
||
|
- */
|
||
|
- assert_se(unsetenv("VAR1") == 0);
|
||
|
- assert_se(unsetenv("VAR2") == 0);
|
||
|
- assert_se(unsetenv("VAR3") == 0);
|
||
|
+ r = manager_new(scope, MANAGER_TEST_RUN_BASIC, &m);
|
||
|
+ if (manager_errno_skip_test(r))
|
||
|
+ return (void) log_tests_skipped_errno(r, "manager_new");
|
||
|
+ assert_se(r >= 0);
|
||
|
+
|
||
|
+ m->default_std_output = EXEC_OUTPUT_NULL; /* don't rely on host journald */
|
||
|
+ assert_se(manager_startup(m, NULL, NULL, NULL) >= 0);
|
||
|
+
|
||
|
+ /* Uncomment below if you want to make debugging logs stored to journal. */
|
||
|
+ //manager_override_log_target(m, LOG_TARGET_AUTO);
|
||
|
+ //manager_override_log_level(m, LOG_DEBUG);
|
||
|
+
|
||
|
+ for (const test_entry *test = tests; test->f; test++)
|
||
|
+ if (strv_fnmatch_or_empty(patterns, test->name, FNM_NOESCAPE))
|
||
|
+ test->f(m);
|
||
|
+ else
|
||
|
+ log_info("Skipping %s because it does not match any pattern.", test->name);
|
||
|
+}
|
||
|
+
|
||
|
+static int prepare_ns(const char *process_name) {
|
||
|
+ int r;
|
||
|
+
|
||
|
+ r = safe_fork(process_name,
|
||
|
+ FORK_RESET_SIGNALS |
|
||
|
+ FORK_CLOSE_ALL_FDS |
|
||
|
+ FORK_DEATHSIG |
|
||
|
+ FORK_WAIT |
|
||
|
+ FORK_REOPEN_LOG |
|
||
|
+ FORK_LOG |
|
||
|
+ FORK_NEW_MOUNTNS |
|
||
|
+ FORK_MOUNTNS_SLAVE,
|
||
|
+ NULL);
|
||
|
+ assert_se(r >= 0);
|
||
|
+ if (r == 0) {
|
||
|
+ _cleanup_free_ char *unit_dir = NULL;
|
||
|
+
|
||
|
+ /* Make "/" read-only. */
|
||
|
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, NULL, "/", NULL, MS_BIND|MS_REMOUNT, NULL) >= 0);
|
||
|
+
|
||
|
+ /* Creating a new user namespace in the above means all MS_SHARED mounts become MS_SLAVE.
|
||
|
+ * Let's put them back to MS_SHARED here, since that's what we want as defaults. (This will
|
||
|
+ * not reconnect propagation, but simply create new peer groups for all our mounts). */
|
||
|
+ assert_se(mount_follow_verbose(LOG_DEBUG, NULL, "/", NULL, MS_SHARED|MS_REC, NULL) >= 0);
|
||
|
+
|
||
|
+ assert_se(mkdir_p(PRIVATE_UNIT_DIR, 0755) >= 0);
|
||
|
+
|
||
|
+ /* Mount tmpfs on the following directories to make not StateDirectory= or friends disturb the host. */
|
||
|
+ FOREACH_STRING(p, "/root", "/tmp", "/var/tmp", "/var/lib", PRIVATE_UNIT_DIR)
|
||
|
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, NULL) >= 0);
|
||
|
|
||
|
- r = run_tests(LOOKUP_SCOPE_USER, user_tests, argv + 1);
|
||
|
- if (r != 0)
|
||
|
- return r;
|
||
|
+ /* Copy unit files to make them accessible even when unprivileged. */
|
||
|
+ assert_se(get_testdata_dir("test-execute/", &unit_dir) >= 0);
|
||
|
+ assert_se(copy_directory(unit_dir, PRIVATE_UNIT_DIR, COPY_MERGE_EMPTY) >= 0);
|
||
|
|
||
|
- r = run_tests(LOOKUP_SCOPE_SYSTEM, system_tests, argv + 1);
|
||
|
- if (r != 0)
|
||
|
- return r;
|
||
|
+ /* Prepare credstore like tmpfiles.d/credstore.conf for LoadCredential= tests. */
|
||
|
+ FOREACH_STRING(p, "/run/credstore", "/run/credstore.encrypted") {
|
||
|
+ assert_se(mkdir_p(p, 0) >= 0);
|
||
|
+ assert_se(mount_nofollow_verbose(LOG_DEBUG, "tmpfs", p, "tmpfs", MS_NOSUID|MS_NODEV, "mode=0000") >= 0);
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ return r;
|
||
|
+}
|
||
|
+
|
||
|
+TEST(run_tests_root) {
|
||
|
+ _cleanup_strv_free_ char **filters = NULL;
|
||
|
+
|
||
|
+ if (!have_namespaces())
|
||
|
+ return (void) log_tests_skipped("unshare() is disabled");
|
||
|
+
|
||
|
+ /* safe_fork() clears saved_argv in the child process. Let's copy it. */
|
||
|
+ assert_se(filters = strv_copy(strv_skip(saved_argv, 1)));
|
||
|
+
|
||
|
+ if (prepare_ns("(test-execute-root)") == 0) {
|
||
|
+ can_unshare = true;
|
||
|
+ run_tests(LOOKUP_SCOPE_SYSTEM, filters);
|
||
|
+ _exit(EXIT_SUCCESS);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+TEST(run_tests_without_unshare) {
|
||
|
+ if (!have_namespaces()) {
|
||
|
+ /* unshare() is already filtered. */
|
||
|
+ can_unshare = false;
|
||
|
+ run_tests(LOOKUP_SCOPE_SYSTEM, strv_skip(saved_argv, 1));
|
||
|
+ return;
|
||
|
+ }
|
||
|
|
||
|
#if HAVE_SECCOMP
|
||
|
+ _cleanup_strv_free_ char **filters = NULL;
|
||
|
+ int r;
|
||
|
+
|
||
|
/* The following tests are for 1beab8b0d0ff2d7d1436b52d4a0c3d56dc908962. */
|
||
|
- if (!is_seccomp_available()) {
|
||
|
- log_notice("Seccomp not available, skipping unshare() filtered tests.");
|
||
|
- return 0;
|
||
|
- }
|
||
|
+ if (!is_seccomp_available())
|
||
|
+ return (void) log_tests_skipped("Seccomp not available, cannot run unshare() filtered tests");
|
||
|
+
|
||
|
+ /* safe_fork() clears saved_argv in the child process. Let's copy it. */
|
||
|
+ assert_se(filters = strv_copy(strv_skip(saved_argv, 1)));
|
||
|
|
||
|
- _cleanup_hashmap_free_ Hashmap *s = NULL;
|
||
|
- assert_se(s = hashmap_new(NULL));
|
||
|
- r = seccomp_syscall_resolve_name("unshare");
|
||
|
- assert_se(r != __NR_SCMP_ERROR);
|
||
|
- assert_se(hashmap_put(s, UINT32_TO_PTR(r + 1), INT_TO_PTR(-1)) >= 0);
|
||
|
- assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EOPNOTSUPP), true) >= 0);
|
||
|
- assert_se(unshare(CLONE_NEWNS) < 0);
|
||
|
- assert_se(errno == EOPNOTSUPP);
|
||
|
+ if (prepare_ns("(test-execute-without-unshare)") == 0) {
|
||
|
+ _cleanup_hashmap_free_ Hashmap *s = NULL;
|
||
|
|
||
|
- can_unshare = false;
|
||
|
+ r = seccomp_syscall_resolve_name("unshare");
|
||
|
+ assert_se(r != __NR_SCMP_ERROR);
|
||
|
+ assert_se(hashmap_ensure_put(&s, NULL, UINT32_TO_PTR(r + 1), INT_TO_PTR(-1)) >= 0);
|
||
|
+ assert_se(seccomp_load_syscall_filter_set_raw(SCMP_ACT_ALLOW, s, SCMP_ACT_ERRNO(EOPNOTSUPP), true) >= 0);
|
||
|
|
||
|
- r = run_tests(LOOKUP_SCOPE_USER, user_tests, argv + 1);
|
||
|
- if (r != 0)
|
||
|
- return r;
|
||
|
+ /* Check unshare() is actually filtered. */
|
||
|
+ assert_se(unshare(CLONE_NEWNS) < 0);
|
||
|
+ assert_se(errno == EOPNOTSUPP);
|
||
|
|
||
|
- return run_tests(LOOKUP_SCOPE_SYSTEM, system_tests, argv + 1);
|
||
|
+ can_unshare = false;
|
||
|
+ run_tests(LOOKUP_SCOPE_SYSTEM, filters);
|
||
|
+ _exit(EXIT_SUCCESS);
|
||
|
+ }
|
||
|
#else
|
||
|
- return 0;
|
||
|
+ log_tests_skipped("Built without seccomp support, cannot run unshare() filtered tests");
|
||
|
+#endif
|
||
|
+}
|
||
|
+
|
||
|
+TEST(run_tests_unprivileged) {
|
||
|
+ _cleanup_strv_free_ char **filters = NULL;
|
||
|
+
|
||
|
+ if (!have_namespaces())
|
||
|
+ return (void) log_tests_skipped("unshare() is disabled");
|
||
|
+
|
||
|
+ /* safe_fork() clears saved_argv in the child process. Let's copy it. */
|
||
|
+ assert_se(filters = strv_copy(strv_skip(saved_argv, 1)));
|
||
|
+
|
||
|
+ if (prepare_ns("(test-execute-unprivileged)") == 0) {
|
||
|
+ assert_se(capability_bounding_set_drop(0, /* right_now = */ true) >= 0);
|
||
|
+
|
||
|
+ can_unshare = false;
|
||
|
+ run_tests(LOOKUP_SCOPE_USER, filters);
|
||
|
+ _exit(EXIT_SUCCESS);
|
||
|
+ }
|
||
|
+}
|
||
|
+
|
||
|
+static int intro(void) {
|
||
|
+#if HAS_FEATURE_ADDRESS_SANITIZER
|
||
|
+ if (strstr_ptr(ci_environment(), "travis") || strstr_ptr(ci_environment(), "github-actions"))
|
||
|
+ return log_tests_skipped("Running on Travis CI/GH Actions under ASan, see https://github.com/systemd/systemd/issues/10696");
|
||
|
#endif
|
||
|
+ /* It is needed otherwise cgroup creation fails */
|
||
|
+ if (geteuid() != 0 || have_effective_cap(CAP_SYS_ADMIN) <= 0)
|
||
|
+ return log_tests_skipped("not privileged");
|
||
|
+
|
||
|
+ if (enter_cgroup_subroot(NULL) == -ENOMEDIUM)
|
||
|
+ return log_tests_skipped("cgroupfs not available");
|
||
|
+
|
||
|
+ if (path_is_read_only_fs("/sys") > 0)
|
||
|
+ return log_tests_skipped("/sys is mounted read-only");
|
||
|
+
|
||
|
+ /* Create dummy network interface for testing PrivateNetwork=yes */
|
||
|
+ (void) system("ip link add dummy-test-exec type dummy");
|
||
|
+
|
||
|
+ return EXIT_SUCCESS;
|
||
|
}
|
||
|
+
|
||
|
+static int outro(void) {
|
||
|
+ (void) system("ip link del dummy-test-exec");
|
||
|
+ (void) rmdir(PRIVATE_UNIT_DIR);
|
||
|
+
|
||
|
+ return EXIT_SUCCESS;
|
||
|
+}
|
||
|
+
|
||
|
+DEFINE_TEST_MAIN_FULL(LOG_DEBUG, intro, outro);
|
||
|
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
|
||
|
index 1c79e4f722..2a5a1e1ff3 100644
|
||
|
--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
|
||
|
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step1.service
|
||
|
@@ -3,14 +3,14 @@
|
||
|
Description=Test DynamicUser= migrate StateDirectory= (preparation)
|
||
|
|
||
|
[Service]
|
||
|
-ExecStart=test -w /var/lib/test-dynamicuser-migrate
|
||
|
-ExecStart=test -w /var/lib/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=test ! -L /var/lib/test-dynamicuser-migrate
|
||
|
-ExecStart=test ! -L /var/lib/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=test -d /var/lib/test-dynamicuser-migrate
|
||
|
-ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=touch /var/lib/test-dynamicuser-migrate/yay
|
||
|
-ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
+ExecStart=test -w %S/test-dynamicuser-migrate
|
||
|
+ExecStart=test -w %S/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=test ! -L %S/test-dynamicuser-migrate
|
||
|
+ExecStart=test ! -L %S/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=test -d %S/test-dynamicuser-migrate
|
||
|
+ExecStart=test -d %S/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=touch %S/test-dynamicuser-migrate/yay
|
||
|
+ExecStart=touch %S/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"'
|
||
|
|
||
|
Type=oneshot
|
||
|
diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
|
||
|
index 015b74ce22..e89f0c5aae 100644
|
||
|
--- a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
|
||
|
+++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service
|
||
|
@@ -3,22 +3,22 @@
|
||
|
Description=Test DynamicUser= migrate StateDirectory=
|
||
|
|
||
|
[Service]
|
||
|
-ExecStart=test -w /var/lib/test-dynamicuser-migrate
|
||
|
-ExecStart=test -w /var/lib/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=test -L /var/lib/test-dynamicuser-migrate
|
||
|
-ExecStart=test -L /var/lib/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=test -d /var/lib/test-dynamicuser-migrate
|
||
|
-ExecStart=test -d /var/lib/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=test -f /var/lib/test-dynamicuser-migrate/yay
|
||
|
-ExecStart=test -f /var/lib/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
-ExecStart=test -d /var/lib/private/test-dynamicuser-migrate
|
||
|
-ExecStart=test -d /var/lib/private/test-dynamicuser-migrate2/hoge
|
||
|
-ExecStart=test -f /var/lib/private/test-dynamicuser-migrate/yay
|
||
|
-ExecStart=test -f /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
-ExecStart=touch /var/lib/test-dynamicuser-migrate/yay
|
||
|
-ExecStart=touch /var/lib/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
-ExecStart=touch /var/lib/private/test-dynamicuser-migrate/yay
|
||
|
-ExecStart=touch /var/lib/private/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
+ExecStart=test -w %S/test-dynamicuser-migrate
|
||
|
+ExecStart=test -w %S/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=test -L %S/test-dynamicuser-migrate
|
||
|
+ExecStart=test -L %S/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=test -d %S/test-dynamicuser-migrate
|
||
|
+ExecStart=test -d %S/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=test -f %S/test-dynamicuser-migrate/yay
|
||
|
+ExecStart=test -f %S/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
+ExecStart=test -d %S/private/test-dynamicuser-migrate
|
||
|
+ExecStart=test -d %S/private/test-dynamicuser-migrate2/hoge
|
||
|
+ExecStart=test -f %S/private/test-dynamicuser-migrate/yay
|
||
|
+ExecStart=test -f %S/private/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
+ExecStart=touch %S/test-dynamicuser-migrate/yay
|
||
|
+ExecStart=touch %S/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
+ExecStart=touch %S/private/test-dynamicuser-migrate/yay
|
||
|
+ExecStart=touch %S/private/test-dynamicuser-migrate2/hoge/yayyay
|
||
|
ExecStart=/bin/sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/test-dynamicuser-migrate2/hoge"'
|
||
|
|
||
|
Type=oneshot
|
||
|
diff --git a/test/test-execute/exec-dynamicuser-statedir.service b/test/test-execute/exec-dynamicuser-statedir.service
|
||
|
index b33b4da74a..b7e36f529e 100644
|
||
|
--- a/test/test-execute/exec-dynamicuser-statedir.service
|
||
|
+++ b/test/test-execute/exec-dynamicuser-statedir.service
|
||
|
@@ -3,71 +3,71 @@
|
||
|
Description=Test DynamicUser= with StateDirectory=
|
||
|
|
||
|
[Service]
|
||
|
-ExecStart=test -w /var/lib/waldo
|
||
|
-ExecStart=test -w /var/lib/quux/pief
|
||
|
-ExecStart=test -w /var/lib/aaa
|
||
|
-ExecStart=test -w /var/lib/aaa/bbb
|
||
|
-ExecStart=test -w /var/lib/aaa/ccc
|
||
|
-ExecStart=test -w /var/lib/xxx
|
||
|
-ExecStart=test -w /var/lib/xxx/yyy
|
||
|
-ExecStart=test -w /var/lib/xxx/zzz
|
||
|
-ExecStart=test -w /var/lib/aaa/111
|
||
|
-ExecStart=test -w /var/lib/aaa/222
|
||
|
-ExecStart=test -w /var/lib/aaa/333
|
||
|
+ExecStart=test -w %S/waldo
|
||
|
+ExecStart=test -w %S/quux/pief
|
||
|
+ExecStart=test -w %S/aaa
|
||
|
+ExecStart=test -w %S/aaa/bbb
|
||
|
+ExecStart=test -w %S/aaa/ccc
|
||
|
+ExecStart=test -w %S/xxx
|
||
|
+ExecStart=test -w %S/xxx/yyy
|
||
|
+ExecStart=test -w %S/xxx/zzz
|
||
|
+ExecStart=test -w %S/aaa/111
|
||
|
+ExecStart=test -w %S/aaa/222
|
||
|
+ExecStart=test -w %S/aaa/333
|
||
|
|
||
|
-ExecStart=test -d /var/lib/waldo
|
||
|
-ExecStart=test -d /var/lib/quux/pief
|
||
|
-ExecStart=test -d /var/lib/aaa
|
||
|
-ExecStart=test -d /var/lib/aaa/bbb
|
||
|
-ExecStart=test -d /var/lib/aaa/ccc
|
||
|
-ExecStart=test -d /var/lib/xxx
|
||
|
-ExecStart=test -d /var/lib/xxx/yyy
|
||
|
-ExecStart=test -d /var/lib/xxx/zzz
|
||
|
-ExecStart=test -L /var/lib/aaa/111
|
||
|
-ExecStart=test -L /var/lib/aaa/222
|
||
|
-ExecStart=test -L /var/lib/aaa/333
|
||
|
+ExecStart=test -d %S/waldo
|
||
|
+ExecStart=test -d %S/quux/pief
|
||
|
+ExecStart=test -d %S/aaa
|
||
|
+ExecStart=test -d %S/aaa/bbb
|
||
|
+ExecStart=test -d %S/aaa/ccc
|
||
|
+ExecStart=test -d %S/xxx
|
||
|
+ExecStart=test -d %S/xxx/yyy
|
||
|
+ExecStart=test -d %S/xxx/zzz
|
||
|
+ExecStart=test -L %S/aaa/111
|
||
|
+ExecStart=test -L %S/aaa/222
|
||
|
+ExecStart=test -L %S/aaa/333
|
||
|
|
||
|
-ExecStart=touch /var/lib/waldo/hoge
|
||
|
-ExecStart=touch /var/lib/quux/pief/hoge
|
||
|
-ExecStart=touch /var/lib/aaa/hoge
|
||
|
-ExecStart=touch /var/lib/aaa/bbb/hoge
|
||
|
-ExecStart=touch /var/lib/aaa/ccc/hoge
|
||
|
-ExecStart=touch /var/lib/xxx/hoge
|
||
|
-ExecStart=touch /var/lib/xxx/yyy/hoge
|
||
|
-ExecStart=touch /var/lib/xxx/zzz/hoge
|
||
|
-ExecStart=touch /var/lib/aaa/111/foo
|
||
|
-ExecStart=touch /var/lib/aaa/222/foo
|
||
|
-ExecStart=touch /var/lib/aaa/333/foo
|
||
|
+ExecStart=touch %S/waldo/hoge
|
||
|
+ExecStart=touch %S/quux/pief/hoge
|
||
|
+ExecStart=touch %S/aaa/hoge
|
||
|
+ExecStart=touch %S/aaa/bbb/hoge
|
||
|
+ExecStart=touch %S/aaa/ccc/hoge
|
||
|
+ExecStart=touch %S/xxx/hoge
|
||
|
+ExecStart=touch %S/xxx/yyy/hoge
|
||
|
+ExecStart=touch %S/xxx/zzz/hoge
|
||
|
+ExecStart=touch %S/aaa/111/foo
|
||
|
+ExecStart=touch %S/aaa/222/foo
|
||
|
+ExecStart=touch %S/aaa/333/foo
|
||
|
|
||
|
-ExecStart=test -f /var/lib/waldo/hoge
|
||
|
-ExecStart=test -f /var/lib/quux/pief/hoge
|
||
|
-ExecStart=test -f /var/lib/aaa/hoge
|
||
|
-ExecStart=test -f /var/lib/aaa/bbb/hoge
|
||
|
-ExecStart=test -f /var/lib/aaa/ccc/hoge
|
||
|
-ExecStart=test -f /var/lib/xxx/hoge
|
||
|
-ExecStart=test -f /var/lib/xxx/yyy/hoge
|
||
|
-ExecStart=test -f /var/lib/xxx/zzz/hoge
|
||
|
-ExecStart=test -f /var/lib/aaa/111/foo
|
||
|
-ExecStart=test -f /var/lib/aaa/222/foo
|
||
|
-ExecStart=test -f /var/lib/aaa/333/foo
|
||
|
-ExecStart=test -f /var/lib/xxx/foo
|
||
|
-ExecStart=test -f /var/lib/xxx/yyy/foo
|
||
|
-ExecStart=test -f /var/lib/xxx/zzz/foo
|
||
|
+ExecStart=test -f %S/waldo/hoge
|
||
|
+ExecStart=test -f %S/quux/pief/hoge
|
||
|
+ExecStart=test -f %S/aaa/hoge
|
||
|
+ExecStart=test -f %S/aaa/bbb/hoge
|
||
|
+ExecStart=test -f %S/aaa/ccc/hoge
|
||
|
+ExecStart=test -f %S/xxx/hoge
|
||
|
+ExecStart=test -f %S/xxx/yyy/hoge
|
||
|
+ExecStart=test -f %S/xxx/zzz/hoge
|
||
|
+ExecStart=test -f %S/aaa/111/foo
|
||
|
+ExecStart=test -f %S/aaa/222/foo
|
||
|
+ExecStart=test -f %S/aaa/333/foo
|
||
|
+ExecStart=test -f %S/xxx/foo
|
||
|
+ExecStart=test -f %S/xxx/yyy/foo
|
||
|
+ExecStart=test -f %S/xxx/zzz/foo
|
||
|
|
||
|
-ExecStart=test -f /var/lib/private/waldo/hoge
|
||
|
-ExecStart=test -f /var/lib/private/quux/pief/hoge
|
||
|
-ExecStart=test -f /var/lib/private/aaa/hoge
|
||
|
-ExecStart=test -f /var/lib/private/aaa/bbb/hoge
|
||
|
-ExecStart=test -f /var/lib/private/aaa/ccc/hoge
|
||
|
-ExecStart=test -f /var/lib/private/xxx/hoge
|
||
|
-ExecStart=test -f /var/lib/private/xxx/yyy/hoge
|
||
|
-ExecStart=test -f /var/lib/private/xxx/zzz/hoge
|
||
|
-ExecStart=test -f /var/lib/private/aaa/111/foo
|
||
|
-ExecStart=test -f /var/lib/private/aaa/222/foo
|
||
|
-ExecStart=test -f /var/lib/private/aaa/333/foo
|
||
|
-ExecStart=test -f /var/lib/private/xxx/foo
|
||
|
-ExecStart=test -f /var/lib/private/xxx/yyy/foo
|
||
|
-ExecStart=test -f /var/lib/private/xxx/zzz/foo
|
||
|
+ExecStart=test -f %S/private/waldo/hoge
|
||
|
+ExecStart=test -f %S/private/quux/pief/hoge
|
||
|
+ExecStart=test -f %S/private/aaa/hoge
|
||
|
+ExecStart=test -f %S/private/aaa/bbb/hoge
|
||
|
+ExecStart=test -f %S/private/aaa/ccc/hoge
|
||
|
+ExecStart=test -f %S/private/xxx/hoge
|
||
|
+ExecStart=test -f %S/private/xxx/yyy/hoge
|
||
|
+ExecStart=test -f %S/private/xxx/zzz/hoge
|
||
|
+ExecStart=test -f %S/private/aaa/111/foo
|
||
|
+ExecStart=test -f %S/private/aaa/222/foo
|
||
|
+ExecStart=test -f %S/private/aaa/333/foo
|
||
|
+ExecStart=test -f %S/private/xxx/foo
|
||
|
+ExecStart=test -f %S/private/xxx/yyy/foo
|
||
|
+ExecStart=test -f %S/private/xxx/zzz/foo
|
||
|
|
||
|
ExecStart=sh -x -c 'test "$$STATE_DIRECTORY" = "%S/aaa:%S/aaa/bbb:%S/aaa/ccc:%S/quux/pief:%S/waldo:%S/xxx:%S/xxx/yyy:%S/xxx/zzz"'
|
||
|
|
||
|
diff --git a/test/test-execute/exec-privatenetwork-yes.service b/test/test-execute/exec-privatenetwork-yes.service
|
||
|
index 0fff048b94..360099d337 100644
|
||
|
--- a/test/test-execute/exec-privatenetwork-yes.service
|
||
|
+++ b/test/test-execute/exec-privatenetwork-yes.service
|
||
|
@@ -4,5 +4,6 @@ Description=Test for PrivateNetwork
|
||
|
|
||
|
[Service]
|
||
|
ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -Ev ": (lo|(erspan|gre|gretap|ip_vti|ip6_vti|ip6gre|ip6tnl|sit|tunl)0@.*):"'
|
||
|
+ExecStart=/bin/sh -x -c '! ip link | grep -E "^[0-9]+: " | grep -F ": dummy-test-exec:"'
|
||
|
Type=oneshot
|
||
|
PrivateNetwork=yes
|
||
|
diff --git a/test/test-execute/exec-specifier-system.service b/test/test-execute/exec-specifier-system.service
|
||
|
new file mode 100644
|
||
|
index 0000000000..9e8ee567aa
|
||
|
--- /dev/null
|
||
|
+++ b/test/test-execute/exec-specifier-system.service
|
||
|
@@ -0,0 +1,11 @@
|
||
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||
|
+[Unit]
|
||
|
+Description=Test for specifiers (system)
|
||
|
+
|
||
|
+[Service]
|
||
|
+Type=oneshot
|
||
|
+ExecStart=test %t = /run
|
||
|
+ExecStart=test %S = /var/lib
|
||
|
+ExecStart=test %C = /var/cache
|
||
|
+ExecStart=test %L = /var/log
|
||
|
+ExecStart=test %E = /etc
|
||
|
diff --git a/test/test-execute/exec-specifier-user.service b/test/test-execute/exec-specifier-user.service
|
||
|
new file mode 100644
|
||
|
index 0000000000..ee0301a426
|
||
|
--- /dev/null
|
||
|
+++ b/test/test-execute/exec-specifier-user.service
|
||
|
@@ -0,0 +1,11 @@
|
||
|
+# SPDX-License-Identifier: LGPL-2.1-or-later
|
||
|
+[Unit]
|
||
|
+Description=Test for specifiers
|
||
|
+
|
||
|
+[Service]
|
||
|
+Type=oneshot
|
||
|
+ExecStart=sh -c 'test %t = $$XDG_RUNTIME_DIR'
|
||
|
+ExecStart=sh -c 'test %S = %h/.config'
|
||
|
+ExecStart=sh -c 'test %C = %h/.cache'
|
||
|
+ExecStart=sh -c 'test %L = %h/.config/log'
|
||
|
+ExecStart=sh -c 'test %E = %h/.config'
|
||
|
diff --git a/test/test-execute/exec-specifier.service b/test/test-execute/exec-specifier.service
|
||
|
index 2b487bae8c..512f786f83 100644
|
||
|
--- a/test/test-execute/exec-specifier.service
|
||
|
+++ b/test/test-execute/exec-specifier.service
|
||
|
@@ -13,11 +13,6 @@ ExecStart=test %I = ""
|
||
|
ExecStart=test %j = specifier
|
||
|
ExecStart=test %J = specifier
|
||
|
ExecStart=test %f = /exec/specifier
|
||
|
-ExecStart=test %t = /run
|
||
|
-ExecStart=test %S = /var/lib
|
||
|
-ExecStart=test %C = /var/cache
|
||
|
-ExecStart=test %L = /var/log
|
||
|
-ExecStart=test %E = /etc
|
||
|
ExecStart=test %T = /tmp
|
||
|
ExecStart=test %V = /var/tmp
|
||
|
ExecStart=test %d = %t/credentials/%n
|
||
|
diff --git a/test/test-execute/exec-specifier@.service b/test/test-execute/exec-specifier@.service
|
||
|
index 69e969f716..cb9d0a182a 100644
|
||
|
--- a/test/test-execute/exec-specifier@.service
|
||
|
+++ b/test/test-execute/exec-specifier@.service
|
||
|
@@ -13,11 +13,6 @@ ExecStart=test %I = foo/bar
|
||
|
ExecStart=test %j = specifier
|
||
|
ExecStart=test %J = specifier
|
||
|
ExecStart=test %f = /foo/bar
|
||
|
-ExecStart=test %t = /run
|
||
|
-ExecStart=test %S = /var/lib
|
||
|
-ExecStart=test %C = /var/cache
|
||
|
-ExecStart=test %L = /var/log
|
||
|
-ExecStart=test %E = /etc
|
||
|
ExecStart=sh -c 'test %u = $$(id -un)'
|
||
|
ExecStart=sh -c 'test %U = $$(id -u)'
|
||
|
ExecStart=sh -c 'test %g = $$(id -gn)'
|