]>
Commit | Line | Data |
---|---|---|
8216741c ILG |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | ||
3 | #include "bpf-lsm.h" | |
4 | #include "load-fragment.h" | |
5 | #include "manager.h" | |
6 | #include "process-util.h" | |
7 | #include "rlimit-util.h" | |
8 | #include "rm-rf.h" | |
9 | #include "service.h" | |
10 | #include "strv.h" | |
11 | #include "tests.h" | |
12 | #include "unit.h" | |
13 | #include "virt.h" | |
14 | ||
15 | static int test_restrict_filesystems(Manager *m, const char *unit_name, const char *file_path, char **allowed_filesystems) { | |
16 | _cleanup_free_ char *exec_start = NULL; | |
17 | _cleanup_(unit_freep) Unit *u = NULL; | |
18 | ExecContext *ec = NULL; | |
8216741c ILG |
19 | int cld_code, r; |
20 | ||
21 | assert_se(u = unit_new(m, sizeof(Service))); | |
22 | assert_se(unit_add_name(u, unit_name) == 0); | |
23 | assert_se(ec = unit_get_exec_context(u)); | |
24 | ||
25 | STRV_FOREACH(allow_filesystem, allowed_filesystems) { | |
26 | r = config_parse_restrict_filesystems( | |
27 | u->id, "filename", 1, "Service", 1, "RestrictFileSystems", 0, | |
28 | *allow_filesystem, ec, u); | |
29 | if (r < 0) | |
30 | return log_unit_error_errno(u, r, "Failed to parse RestrictFileSystems: %m"); | |
31 | } | |
32 | ||
33 | assert_se(exec_start = strjoin("cat ", file_path)); | |
34 | r = config_parse_exec(u->id, "filename", 1, "Service", 1, "ExecStart", | |
35 | SERVICE_EXEC_START, exec_start, SERVICE(u)->exec_command, u); | |
36 | if (r < 0) | |
37 | return log_error_errno(r, "Failed to parse ExecStart"); | |
38 | ||
39 | SERVICE(u)->type = SERVICE_ONESHOT; | |
40 | u->load_state = UNIT_LOADED; | |
41 | ||
42 | r = unit_start(u); | |
43 | if (r < 0) | |
44 | return log_error_errno(r, "Unit start failed %m"); | |
45 | ||
46 | while (!IN_SET(SERVICE(u)->state, SERVICE_DEAD, SERVICE_FAILED)) { | |
47 | r = sd_event_run(m->event, UINT64_MAX); | |
48 | if (r < 0) | |
49 | return log_error_errno(errno, "Event run failed %m"); | |
50 | } | |
51 | ||
52 | cld_code = SERVICE(u)->exec_command[SERVICE_EXEC_START]->exec_status.code; | |
606309d5 | 53 | if (cld_code != CLD_EXITED) |
8216741c | 54 | return log_error_errno(-SYNTHETIC_ERRNO(EBUSY), "ExecStart didn't exited, code='%s'", sigchld_code_to_string(cld_code)); |
8216741c | 55 | |
606309d5 | 56 | if (SERVICE(u)->state != SERVICE_DEAD) |
8216741c | 57 | return log_error_errno(-SYNTHETIC_ERRNO(EBUSY), "Service is not dead"); |
8216741c ILG |
58 | |
59 | return 0; | |
60 | } | |
61 | ||
62 | int main(int argc, char *argv[]) { | |
63 | _cleanup_(rm_rf_physical_and_freep) char *runtime_dir = NULL; | |
64 | _cleanup_(manager_freep) Manager *m = NULL; | |
65 | _cleanup_free_ char *unit_dir = NULL; | |
66 | struct rlimit rl; | |
67 | int r; | |
68 | ||
69 | test_setup_logging(LOG_DEBUG); | |
70 | ||
71 | if (getuid() != 0) | |
72 | return log_tests_skipped("not running as root"); | |
73 | ||
74 | assert_se(getrlimit(RLIMIT_MEMLOCK, &rl) >= 0); | |
75 | rl.rlim_cur = rl.rlim_max = MAX(rl.rlim_max, CAN_MEMLOCK_SIZE); | |
76 | (void) setrlimit_closest(RLIMIT_MEMLOCK, &rl); | |
77 | ||
78 | if (!can_memlock()) | |
4a55ce8f | 79 | return log_tests_skipped("Can't use mlock()"); |
8216741c ILG |
80 | |
81 | r = lsm_bpf_supported(); | |
82 | if (r <= 0) | |
83 | return log_tests_skipped("LSM BPF hooks are not supported"); | |
84 | ||
85 | r = enter_cgroup_subroot(NULL); | |
86 | if (r == -ENOMEDIUM) | |
87 | return log_tests_skipped("cgroupfs not available"); | |
88 | ||
89 | assert_se(get_testdata_dir("units", &unit_dir) >= 0); | |
90 | assert_se(set_unit_path(unit_dir) >= 0); | |
91 | assert_se(runtime_dir = setup_fake_runtime_dir()); | |
92 | ||
93 | assert_se(manager_new(UNIT_FILE_SYSTEM, MANAGER_TEST_RUN_BASIC, &m) >= 0); | |
94 | assert_se(manager_startup(m, NULL, NULL, NULL) >= 0); | |
95 | ||
96 | /* We need to enable access to the filesystem where the binary is so we | |
97 | * add @common-block */ | |
98 | assert_se(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/tracing/printk_formats", STRV_MAKE("@common-block")) < 0); | |
99 | assert_se(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/tracing/printk_formats", STRV_MAKE("tracefs", "@common-block")) >= 0); | |
100 | assert_se(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/tracing/printk_formats", STRV_MAKE("tracefs", "@common-block", "~tracefs")) < 0); | |
101 | assert_se(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/debug/sleep_time", STRV_MAKE("@common-block")) < 0); | |
102 | assert_se(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/debug/sleep_time", STRV_MAKE("debugfs", "@common-block")) >= 0); | |
103 | assert_se(test_restrict_filesystems(m, "restrict_filesystems_test.service", "/sys/kernel/debug/sleep_time", STRV_MAKE("~debugfs")) < 0); | |
104 | ||
105 | return 0; | |
106 | } |