]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Create helper function to capture output
authorMichael Tremer <michael.tremer@ipfire.org>
Sat, 19 Oct 2024 12:47:13 +0000 (12:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sat, 19 Oct 2024 12:47:13 +0000 (12:47 +0000)
That way, we can have the length as an extra argument.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/build.c
src/libpakfire/include/pakfire/jail.h
src/libpakfire/jail.c
src/libpakfire/parser.c
tests/libpakfire/cgroup.c
tests/libpakfire/jail.c

index 4704239cf9a6dc55a20991184c599301e2e3aa95..f24d9eaadda8659b30ee65364a07572084656b7f 100644 (file)
@@ -2466,7 +2466,7 @@ PAKFIRE_EXPORT int pakfire_build_shell(struct pakfire_build* build, const char*
 
        // Run the command (if given)
        if (argv)
-               return pakfire_jail_exec(build->jail, argv, 0, NULL);
+               return pakfire_jail_exec(build->jail, argv, 0);
 
        // Otherwise run the shell
        return pakfire_jail_shell(build->jail);
index 72338a641bb91af25edf14ec60af3b0fbec1459f..4b82b08bdfad9285f51f071f1ca0ec440461a718 100644 (file)
@@ -68,7 +68,10 @@ enum pakfire_jail_exec_flags {
        PAKFIRE_JAIL_HAS_LOOP_DEVICES = (1 << 3),
 };
 
-int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], int flags, char** output);
+int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], int flags);
+
+int pakfire_jail_exec_capture_output(struct pakfire_jail* jail,
+       const char* argv[], int flags, char** output, size_t* length);
 
 // Resource limits
 int pakfire_jail_set_cgroup(struct pakfire_jail* jail, struct pakfire_cgroup* cgroup);
@@ -79,7 +82,8 @@ int pakfire_jail_communicate(
        pakfire_pty_stdout_callback stdout_callback, void* stdout_data);
 
 // Convenience functions
-int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, char** output);
+int pakfire_jail_run(struct pakfire* pakfire,
+       const char* argv[], int flags, char** output, size_t* output_length);
 int pakfire_jail_run_script(struct pakfire* pakfire,
        const char* script, const size_t length, const char* argv[], int flags);
 
index cb144a02f438956fbb6a11be478da41895782b54..bfca392a656ec78d442cebede9dd7ca5a47cc2f9 100644 (file)
@@ -1341,7 +1341,7 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail,
                const char* argv[], int flags,
                pakfire_pty_stdin_callback stdin_callback, void* stdin_data,
                pakfire_pty_stdout_callback stdout_callback, void* stdout_data,
-               char** output) {
+               char** output, size_t* output_length) {
        int pty_flags = 0;
        int r;
 
@@ -1522,9 +1522,8 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail,
        }
 
        // Return the output
-       if (output) {
-               *output = pakfire_pty_output(ctx.pty, NULL);
-       }
+       if (output)
+               *output = pakfire_pty_output(ctx.pty, output_length);
 
 ERROR:
        // Destroy the temporary cgroup (if any)
@@ -1560,9 +1559,13 @@ ERROR:
        return ctx.exit;
 }
 
-int pakfire_jail_exec(struct pakfire_jail* jail,
-               const char* argv[], int flags, char** output) {
-       return __pakfire_jail_exec(jail, argv, flags, NULL, NULL, NULL, NULL, output);
+int pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[], int flags) {
+       return __pakfire_jail_exec(jail, argv, flags, NULL, NULL, NULL, NULL, NULL, NULL);
+}
+
+int pakfire_jail_exec_capture_output(struct pakfire_jail* jail,
+               const char* argv[], int flags, char** output, size_t* length) {
+       return __pakfire_jail_exec(jail, argv, flags, NULL, NULL, NULL, NULL, output, length);
 }
 
 int pakfire_jail_communicate(
@@ -1570,7 +1573,7 @@ int pakfire_jail_communicate(
                pakfire_pty_stdin_callback stdin_callback, void* stdin_data,
                pakfire_pty_stdout_callback stdout_callback, void* stdout_data) {
        return __pakfire_jail_exec(jail, argv, flags,
-               stdin_callback, stdin_data, stdout_callback, stdout_data, NULL);
+               stdin_callback, stdin_data, stdout_callback, stdout_data, NULL, NULL);
 }
 
 int pakfire_jail_exec_script(struct pakfire_jail* jail,
@@ -1655,7 +1658,8 @@ ERROR:
        A convenience function that creates a new jail, runs the given command and destroys
        the jail again.
 */
-int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, char** output) {
+int pakfire_jail_run(struct pakfire* pakfire,
+               const char* argv[], int flags, char** output, size_t* output_length) {
        struct pakfire_jail* jail = NULL;
        int r;
 
@@ -1665,7 +1669,7 @@ int pakfire_jail_run(struct pakfire* pakfire, const char* argv[], int flags, cha
                goto ERROR;
 
        // Execute the command
-       r = pakfire_jail_exec(jail, argv, flags, output);
+       r = pakfire_jail_exec_capture_output(jail, argv, flags, output, output_length);
 
 ERROR:
        if (jail)
@@ -1718,7 +1722,7 @@ int pakfire_jail_shell(struct pakfire_jail* jail) {
        }
 
        // Execute /bin/bash
-       r = pakfire_jail_exec(jail, argv, PAKFIRE_JAIL_INTERACTIVE, NULL);
+       r = pakfire_jail_exec(jail, argv, PAKFIRE_JAIL_INTERACTIVE);
 
        // Raise any errors
        if (r < 0)
@@ -1746,7 +1750,7 @@ static int pakfire_jail_run_if_possible(struct pakfire* pakfire, const char** ar
                goto ERROR;
        }
 
-       r = pakfire_jail_run(pakfire, argv, 0, NULL);
+       r = pakfire_jail_run(pakfire, argv, 0, NULL, NULL);
 
 ERROR:
        if (ctx)
index b7a4a0cb4d80c6b46fa72973b603d7074eda8a68..dbe7702f903de1841eacd76a1cfcd1e2d0a9e5b8 100644 (file)
@@ -476,9 +476,10 @@ static int pakfire_parser_expand_commands(struct pakfire_parser* parser, char**
 
                // The output of the command
                char* output = NULL;
+               size_t length = 0;
 
                // Execute the command inside the Pakfire environment
-               r = pakfire_jail_run(parser->pakfire, argv, 0, &output);
+               r = pakfire_jail_run(parser->pakfire, argv, 0, &output, &length);
                if (r) {
                        // Just log this and continue
                        DEBUG(parser->pakfire, "Command '%s' failed with return code %d\n", command, r);
index dd00a460b3e8d18130bc80a413a34b167644d43d..9cc41133464153d613db03b0f297d0445244a6df 100644 (file)
@@ -74,7 +74,7 @@ static int test_stats(const struct test* t) {
 
        // Run a few things
        for (unsigned int i = 0; i < 3; i++) {
-               ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, NULL));
+               ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0));
        }
 
        // Try reading the stats into some invalid space
index e5b71fc0caa1858a29347f0489eefe11b8eca5d1..594124e2f4a848748d93fb6de0de52be2a8d8b77 100644 (file)
@@ -68,7 +68,7 @@ static int test_exit_code(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Check if we receive the correct exit code
-       ASSERT(pakfire_jail_exec(jail, argv, 0, NULL) == 123);
+       ASSERT(pakfire_jail_exec(jail, argv, 0) == 123);
 
        // Success
        r = EXIT_SUCCESS;
@@ -92,7 +92,7 @@ static int test_segv(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Check if we receive the correct exit code
-       ASSERT(pakfire_jail_exec(jail, argv, 0, NULL) == 139);
+       ASSERT(pakfire_jail_exec(jail, argv, 0) == 139);
 
        // Success
        r = EXIT_SUCCESS;
@@ -135,15 +135,17 @@ FAIL:
 static int test_exec(const struct test* t) {
        struct pakfire_jail* jail = NULL;
        char* output = NULL;
+       size_t length = 0;
 
        // Create a new jail
        ASSERT_SUCCESS(pakfire_jail_create(&jail, t->pakfire));
 
        // Try to execute something
-       ASSERT_SUCCESS(pakfire_jail_exec(jail, cmd_hello_world, 0, &output));
+       ASSERT_SUCCESS(pakfire_jail_exec_capture_output(jail, cmd_hello_world, 0, &output, &length));
 
        // We should have some output
        ASSERT_STRING_EQUALS(output, "Hello World!\n");
+       ASSERT_EQUALS(length, strlen("Hello World!\n"));
 
        // Destroy it
        ASSERT_NULL(pakfire_jail_unref(jail));
@@ -169,7 +171,7 @@ static int test_launch_into_cgroup(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_set_cgroup(jail, cgroup));
 
        // Run command
-       ASSERT(pakfire_jail_exec(jail, cmd_hello_world, 0, NULL) == 0);
+       ASSERT(pakfire_jail_exec(jail, cmd_hello_world, 0) == 0);
 
        r = EXIT_SUCCESS;
 
@@ -204,7 +206,7 @@ static int test_nice(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_nice(jail, 5));
 
        // Check if the nice level has been set
-       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, &output));
+       ASSERT_SUCCESS(pakfire_jail_exec_capture_output(jail, argv, 0, &output, NULL));
        ASSERT_STRING_EQUALS(output, "5\n");
 
        // Success
@@ -238,10 +240,10 @@ static int test_memory_limit(const struct test* t) {
        ASSERT_SUCCESS(pakfire_cgroup_set_memory_limit(cgroup, 100 * 1024 * 1024));
 
        // Try to exhaust all memory
-       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_exhaust_memory, 0, NULL));
+       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_exhaust_memory, 0));
 
        // A fork bomb should also exhaust all memory
-       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0, NULL));
+       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -275,7 +277,7 @@ static int test_pid_limit(const struct test* t) {
        ASSERT_SUCCESS(pakfire_cgroup_set_pid_limit(cgroup, 100));
 
        // Try to fork as many processes as possible
-       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0, NULL));
+       ASSERT_FAILURE(pakfire_jail_exec(jail, cmd_fork_bomb, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -296,7 +298,7 @@ static int test_file_ownership(const struct test* t) {
        char* output = NULL;
 
        // Execute a simple command
-       ASSERT_SUCCESS(pakfire_jail_run(t->pakfire, cmd_stat_ownership, 0, &output));
+       ASSERT_SUCCESS(pakfire_jail_run(t->pakfire, cmd_stat_ownership, 0, &output, NULL));
 
        // Check if the file has been mapped to root/root
        ASSERT_STRING_EQUALS(output, "uid=0 gid=0\n");
@@ -334,7 +336,7 @@ static int test_bind(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_bind(jail, source, target, MS_RDONLY));
 
        // Check if the mount actually works
-       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0, NULL));
+       ASSERT_SUCCESS(pakfire_jail_exec(jail, argv, 0));
 
        // Success
        r = EXIT_SUCCESS;
@@ -403,7 +405,7 @@ static int test_send_one_signal(const struct test* t,
        };
 
        // Perform the command
-       return pakfire_jail_exec(jail, argv, 0, NULL);
+       return pakfire_jail_exec(jail, argv, 0);
 }
 
 static int test_send_signal(const struct test* t) {
@@ -447,7 +449,7 @@ static int test_timeout(const struct test* t) {
        ASSERT_SUCCESS(pakfire_jail_set_timeout(jail, 1));
 
        // Check if we receive the correct exit code
-       ASSERT(pakfire_jail_exec(jail, argv, 0, NULL) == 139);
+       ASSERT(pakfire_jail_exec(jail, argv, 0) == 139);
 
        // Success
        r = EXIT_SUCCESS;