From: Michael Tremer Date: Tue, 2 Aug 2022 10:35:30 +0000 (+0000) Subject: jail: Implement first steps of running a command in jail X-Git-Tag: 0.9.28~639 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0bd84dc1b608629133147500fb335cf229307b48;p=pakfire.git jail: Implement first steps of running a command in jail Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 4dfdb5eb8..b65f2bda6 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -19,7 +19,13 @@ #############################################################################*/ #include +#include +#include +#include #include +#include +#include +#include #include #include @@ -49,6 +55,10 @@ struct pakfire_jail { char* env[ENVIRON_SIZE]; }; +static int clone3(struct clone_args* args, size_t size) { + return syscall(__NR_clone3, args, size); +} + static void pakfire_jail_free(struct pakfire_jail* jail) { DEBUG(jail->pakfire, "Freeing jail at %p\n", jail); @@ -208,7 +218,63 @@ int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* return 0; } +static int pakfire_jail_child(struct pakfire_jail* jail, const char* argv[]) { + // XXX do we have to reconfigure logging here? + + DEBUG(jail->pakfire, "Launched child process in jail with PID %d\n", getpid()); + + return 0; +} + // Run a command in the jail int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[]) { - return 1; // TODO + int r; + + DEBUG(jail->pakfire, "Executing jail...\n"); + + // Configure child process + struct clone_args args = { + .flags = + CLONE_NEWCGROUP | + CLONE_NEWIPC | + CLONE_NEWNS | + CLONE_NEWPID | + CLONE_NEWUSER | + CLONE_NEWUTS, + .exit_signal = SIGCHLD, + }; + + // Fork this process + pid_t pid = clone3(&args, sizeof(args)); + if (pid < 0) { + ERROR(jail->pakfire, "Could not clone: %m\n"); + return -1; + + // Child process + } else if (pid == 0) { + r = pakfire_jail_child(jail, argv); + _exit(r); + } + + // Set some useful error code + int exit; + int status = 0; + + DEBUG(jail->pakfire, "Waiting for PID %d to finish its work\n", pid); + + if (!status) + waitpid(pid, &status, 0); + + if (WIFEXITED(status)) { + exit = WEXITSTATUS(status); + + DEBUG(jail->pakfire, "Child process exited with code: %d\n", exit); + } else { + ERROR(jail->pakfire, "Could not determine the exit status of process %d\n", pid); + + errno = ESRCH; + exit = -1; + } + + return exit; } diff --git a/tests/libpakfire/jail.c b/tests/libpakfire/jail.c index 48a42db4f..ec8987393 100644 --- a/tests/libpakfire/jail.c +++ b/tests/libpakfire/jail.c @@ -75,10 +75,33 @@ FAIL: return EXIT_FAILURE; } +static int test_exec(const struct test* t) { + struct pakfire_jail* jail = NULL; + + const char* argv[] = { + "/does-not-exist", + NULL, + }; + + // Create a new jail + ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire, 0)); + + // Try to execute something + ASSERT_SUCCESS(pakfire_jail_exec(jail, argv)); + + // Destroy it + ASSERT_NULL(pakfire_jail_unref(jail)); + + return EXIT_SUCCESS; + +FAIL: + return EXIT_FAILURE; +} int main(int argc, char** argv) { testsuite_add_test(test_create); testsuite_add_test(test_env); + testsuite_add_test(test_exec); return testsuite_run(); }