]>
git.ipfire.org Git - pakfire.git/blob - tests/libpakfire/jail.c
1 /*#############################################################################
3 # Pakfire - The IPFire package management system #
4 # Copyright (C) 2022 Pakfire development team #
6 # This program is free software: you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation, either version 3 of the License, or #
9 # (at your option) any later version. #
11 # This program is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
16 # You should have received a copy of the GNU General Public License #
17 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
19 #############################################################################*/
21 #include <sys/mount.h>
23 #include <pakfire/cgroup.h>
24 #include <pakfire/jail.h>
26 #include "../testsuite.h"
28 static const char* cmd_hello_world
[] = {
29 "/command", "echo", "Hello World!", NULL
,
32 static const char* cmd_exhaust_memory
[] = {
33 "/command", "exhaust-memory", NULL
,
36 static const char* cmd_fork_bomb
[] = {
37 "/command", "fork-bomb", NULL
,
40 static const char* cmd_stat_ownership
[] = {
41 "/command", "stat-ownership", NULL
,
44 static int test_create(const struct test
* t
) {
45 struct pakfire_jail
* jail
= NULL
;
48 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
51 ASSERT_NULL(pakfire_jail_unref(jail
));
53 // Create an interactive jail
54 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, PAKFIRE_JAIL_INTERACTIVE
));
57 ASSERT_NULL(pakfire_jail_unref(jail
));
65 static int test_env(const struct test
* t
) {
66 struct pakfire_jail
* jail
= NULL
;
69 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
71 // Check if the default variables are set
72 ASSERT(pakfire_jail_get_env(jail
, "LANG"));
73 ASSERT(pakfire_jail_get_env(jail
, "TERM"));
75 // Fetch a non-existing environment variable
76 ASSERT_NULL(pakfire_jail_get_env(jail
, "VARIABLE"));
79 ASSERT_SUCCESS(pakfire_jail_set_env(jail
, "VARIABLE", "VALUE"));
81 // Read the value back
82 ASSERT_STRING_EQUALS(pakfire_jail_get_env(jail
, "VARIABLE"), "VALUE");
85 ASSERT_NULL(pakfire_jail_unref(jail
));
93 static int test_exec(const struct test
* t
) {
94 struct pakfire_jail
* jail
= NULL
;
97 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
99 // Try to execute something
100 ASSERT_SUCCESS(pakfire_jail_exec(jail
, cmd_hello_world
, NULL
));
103 ASSERT_NULL(pakfire_jail_unref(jail
));
111 static int test_launch_into_cgroup(const struct test
* t
) {
112 struct pakfire_cgroup
* cgroup
= NULL
;
113 struct pakfire_jail
* jail
= NULL
;
114 int r
= EXIT_FAILURE
;
116 // Create a new cgroup
117 ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup
, t
->pakfire
, "pakfire-test", 0));
120 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
122 // Connect jail to the cgroup
123 ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail
, cgroup
));
126 ASSERT(pakfire_jail_exec(jail
, cmd_hello_world
, NULL
) == 0);
132 pakfire_cgroup_destroy(cgroup
);
133 pakfire_cgroup_unref(cgroup
);
136 pakfire_jail_unref(jail
);
141 static int test_nice(const struct test
* t
) {
142 struct pakfire_jail
* jail
= NULL
;
144 int r
= EXIT_FAILURE
;
146 const char* argv
[] = {
147 "/command", "print-nice", NULL
,
151 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
153 // Set invalid nice levels
154 ASSERT_ERRNO(pakfire_jail_nice(jail
, 100), EINVAL
);
155 ASSERT_ERRNO(pakfire_jail_nice(jail
, -100), EINVAL
);
157 // Set something sane
158 ASSERT_SUCCESS(pakfire_jail_nice(jail
, 5));
160 // Check if the nice level has been set
161 ASSERT_SUCCESS(pakfire_jail_exec(jail
, argv
, &output
));
162 ASSERT_STRING_EQUALS(output
, "5\n");
169 pakfire_jail_unref(jail
);
176 static int test_memory_limit(const struct test
* t
) {
177 struct pakfire_cgroup
* cgroup
= NULL
;
178 struct pakfire_jail
* jail
= NULL
;
179 int r
= EXIT_FAILURE
;
183 ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup
, t
->pakfire
, "pakfire-test", 0));
186 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
188 // Connect jail to the cgroup
189 ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail
, cgroup
));
191 // Set a memory limit of 100 MiB
192 ASSERT_SUCCESS(pakfire_cgroup_set_memory_limit(cgroup
, 100 * 1024 * 1024));
194 // Try to exhaust all memory
195 ASSERT_FAILURE(pakfire_jail_exec(jail
, cmd_exhaust_memory
, NULL
));
197 // A fork bomb should also exhaust all memory
198 ASSERT_FAILURE(pakfire_jail_exec(jail
, cmd_fork_bomb
, NULL
));
205 pakfire_jail_unref(jail
);
207 pakfire_cgroup_destroy(cgroup
);
208 pakfire_cgroup_unref(cgroup
);
214 static int test_pid_limit(const struct test
* t
) {
215 struct pakfire_cgroup
* cgroup
= NULL
;
216 struct pakfire_jail
* jail
= NULL
;
217 int r
= EXIT_FAILURE
;
220 ASSERT_SUCCESS(pakfire_cgroup_open(&cgroup
, t
->pakfire
, "pakfire-test", 0));
223 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
225 // Connect jail to the cgroup
226 ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail
, cgroup
));
228 // Set a PID limit of 100 processes
229 ASSERT_SUCCESS(pakfire_cgroup_set_pid_limit(cgroup
, 100));
231 // Try to fork as many processes as possible
232 ASSERT_FAILURE(pakfire_jail_exec(jail
, cmd_fork_bomb
, NULL
));
239 pakfire_jail_unref(jail
);
241 pakfire_cgroup_destroy(cgroup
);
242 pakfire_cgroup_unref(cgroup
);
248 static int test_file_ownership(const struct test
* t
) {
249 int r
= EXIT_FAILURE
;
252 // Execute a simple command
253 ASSERT_SUCCESS(pakfire_jail_run(t
->pakfire
, cmd_stat_ownership
, 0, &output
));
255 // Check if the file has been mapped to root/root
256 ASSERT_STRING_EQUALS(output
, "uid=0 gid=0\n");
268 static int test_bind(const struct test
* t
) {
269 struct pakfire_jail
* jail
= NULL
;
271 int r
= EXIT_FAILURE
;
273 const char* source
= "/";
274 const char* target
= "/oldroot";
276 const char* argv
[] = {
277 "/command", "check-mountpoint", target
, NULL
,
281 ASSERT_SUCCESS(pakfire_jail_create(&jail
, t
->pakfire
, 0));
283 // Bind-mount nonsense
284 ASSERT_ERRNO(pakfire_jail_bind(jail
, NULL
, target
, 0), EINVAL
);
285 ASSERT_ERRNO(pakfire_jail_bind(jail
, source
, NULL
, 0), EINVAL
);
287 // Bind-mount something
288 ASSERT_SUCCESS(pakfire_jail_bind(jail
, source
, target
, MS_RDONLY
));
290 // Check if the mount actually works
291 ASSERT_SUCCESS(pakfire_jail_exec(jail
, argv
, NULL
));
298 pakfire_jail_unref(jail
);
303 int main(int argc
, const char* argv
[]) {
304 testsuite_add_test(test_create
);
305 testsuite_add_test(test_env
);
306 testsuite_add_test(test_exec
);
307 testsuite_add_test(test_launch_into_cgroup
);
308 testsuite_add_test(test_nice
);
309 testsuite_add_test(test_memory_limit
);
310 testsuite_add_test(test_pid_limit
);
311 testsuite_add_test(test_file_ownership
);
312 testsuite_add_test(test_bind
);
314 return testsuite_run(argc
, argv
);