+/* SPDX-License-Identifier: LGPL-2.1+ */
/***
This file is part of systemd.
#include <sys/prctl.h>
#include <sys/types.h>
+#include "errno-list.h"
#include "fileio.h"
#include "fs-util.h"
#include "macro.h"
#include "mkdir.h"
#include "path-util.h"
#include "rm-rf.h"
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
#include "seccomp-util.h"
#endif
#include "stat-util.h"
static void check(Manager *m, Unit *unit, int status_expected, int code_expected) {
Service *service = NULL;
usec_t ts;
- usec_t timeout = 2 * USEC_PER_SEC;
+ usec_t timeout = 2 * USEC_PER_MINUTE;
assert_se(m);
assert_se(unit);
printf("%s\n", unit->id);
exec_context_dump(&service->exec_context, stdout, "\t");
ts = now(CLOCK_MONOTONIC);
- while (service->state != SERVICE_DEAD && service->state != SERVICE_FAILED) {
+ while (!IN_SET(service->state, SERVICE_DEAD, SERVICE_FAILED)) {
int r;
usec_t n;
check(m, unit, status_expected, code_expected);
}
+static void test_exec_bind_paths(Manager *m) {
+ assert_se(mkdir_p("/tmp/test-exec_bind_paths", 0755) >= 0);
+ assert_se(mkdir_p("/tmp/test-exec_bind_readonly_paths", 0755) >= 0);
+
+ test(m, "exec-bind-paths.service", 0, CLD_EXITED);
+
+ (void) rm_rf("/tmp/test-exec_bind_paths", REMOVE_ROOT|REMOVE_PHYSICAL);
+ (void) rm_rf("/tmp/test-exec_bind_readonly_paths", REMOVE_ROOT|REMOVE_PHYSICAL);
+}
+
static void test_exec_workingdirectory(Manager *m) {
assert_se(mkdir_p("/tmp/test-exec_workingdirectory", 0755) >= 0);
test(m, "exec-readonlypaths.service", 0, CLD_EXITED);
test(m, "exec-readonlypaths-mount-propagation.service", 0, CLD_EXITED);
+ test(m, "exec-readonlypaths-with-bindpaths.service", 0, CLD_EXITED);
}
static void test_exec_readwritepaths(Manager *m) {
test(m, "exec-inaccessiblepaths-mount-propagation.service", 0, CLD_EXITED);
}
+static void test_exec_inaccessiblepaths_proc(Manager *m) {
+ if (!is_inaccessible_available()) {
+ log_notice("testing without inaccessible, skipping %s", __func__);
+ return;
+ }
+
+ test(m, "exec-inaccessiblepaths-proc.service", 0, CLD_EXITED);
+}
+
static void test_exec_systemcallfilter(Manager *m) {
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
if (!is_seccomp_available())
return;
test(m, "exec-systemcallfilter-not-failing.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-not-failing2.service", 0, CLD_EXITED);
test(m, "exec-systemcallfilter-failing.service", SIGSYS, CLD_KILLED);
test(m, "exec-systemcallfilter-failing2.service", SIGSYS, CLD_KILLED);
+ test(m, "exec-systemcallfilter-with-errno-name.service", errno_from_name("EILSEQ"), CLD_EXITED);
+ test(m, "exec-systemcallfilter-with-errno-number.service", 255, CLD_EXITED);
#endif
}
static void test_exec_systemcallerrornumber(Manager *m) {
-#ifdef HAVE_SECCOMP
- if (is_seccomp_available())
- test(m, "exec-systemcallerrornumber.service", 1, CLD_EXITED);
+#if HAVE_SECCOMP
+ if (!is_seccomp_available())
+ return;
+ test(m, "exec-systemcallerrornumber-name.service", errno_from_name("EACCES"), CLD_EXITED);
+ test(m, "exec-systemcallerrornumber-number.service", 255, CLD_EXITED);
#endif
}
static void test_exec_restrict_namespaces(Manager *m) {
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
if (!is_seccomp_available())
return;
}
static void test_exec_systemcall_system_mode_with_user(Manager *m) {
-#ifdef HAVE_SECCOMP
+#if HAVE_SECCOMP
if (!is_seccomp_available())
return;
if (getpwnam("nobody"))
test(m, "exec-dynamicuser-fixeduser.service", 0, CLD_EXITED);
test(m, "exec-dynamicuser-fixeduser-one-supplementarygroup.service", 0, CLD_EXITED);
test(m, "exec-dynamicuser-supplementarygroups.service", 0, CLD_EXITED);
+ test(m, "exec-dynamicuser-state-dir.service", 0, CLD_EXITED);
}
static void test_exec_environment(Manager *m) {
test(m, "exec-read-only-path-succeed.service", 0, CLD_EXITED);
}
+static void test_exec_unset_environment(Manager *m) {
+ test(m, "exec-unset-environment.service", 0, CLD_EXITED);
+}
+
+static void test_exec_specifier(Manager *m) {
+ test(m, "exec-specifier.service", 0, CLD_EXITED);
+}
+
static int run_tests(UnitFileScope scope, const test_function_t *tests) {
const test_function_t *test = NULL;
Manager *m = NULL;
assert_se(tests);
- r = manager_new(scope, true, &m);
+ r = manager_new(scope, MANAGER_TEST_RUN_MINIMAL, &m);
if (MANAGER_SKIP_TEST(r)) {
log_notice_errno(r, "Skipping test: manager_new: %m");
return EXIT_TEST_SKIP;
int main(int argc, char *argv[]) {
static const test_function_t user_tests[] = {
+ test_exec_bind_paths,
test_exec_workingdirectory,
test_exec_personality,
test_exec_ignoresigpipe,
test_exec_readonlypaths,
test_exec_readwritepaths,
test_exec_inaccessiblepaths,
+ test_exec_inaccessiblepaths_proc,
test_exec_privatenetwork,
test_exec_systemcallfilter,
test_exec_systemcallerrornumber,
test_exec_user,
test_exec_group,
test_exec_supplementary_groups,
- test_exec_dynamic_user,
test_exec_environment,
test_exec_environmentfile,
test_exec_passenvironment,
test_exec_ioschedulingclass,
test_exec_spec_interpolation,
test_exec_read_only_path_suceed,
+ test_exec_unset_environment,
NULL,
};
static const test_function_t system_tests[] = {
test_exec_systemcall_system_mode_with_user,
+ test_exec_dynamic_user,
+ test_exec_specifier,
NULL,
};
int r;
/* It is needed otherwise cgroup creation fails */
if (getuid() != 0) {
- printf("Skipping test: not root\n");
+ puts("Skipping test: not root");
+ return EXIT_TEST_SKIP;
+ }
+
+ r = enter_cgroup_subroot();
+ if (r == -ENOMEDIUM) {
+ puts("Skipping test: cgroupfs not available");
return EXIT_TEST_SKIP;
}