From: Michael Tremer Date: Sun, 29 Dec 2024 12:52:10 +0000 (+0000) Subject: jail: Create a callback function that is called in the child process X-Git-Tag: 0.9.30~681 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5020e1ea4751a21a26048d5c886eb93aeec49c76;p=pakfire.git jail: Create a callback function that is called in the child process Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/include/pakfire/jail.h b/src/libpakfire/include/pakfire/jail.h index 4b82b08bd..6aac94bda 100644 --- a/src/libpakfire/include/pakfire/jail.h +++ b/src/libpakfire/include/pakfire/jail.h @@ -49,6 +49,8 @@ const char* pakfire_jail_get_env(struct pakfire_jail* jail, const char* key); int pakfire_jail_set_env(struct pakfire_jail* jail, const char* key, const char* value); int pakfire_jail_import_env(struct pakfire_jail* jail, const char* env[]); +typedef int (*pakfire_jail_callback)(struct pakfire_jail* jail, void* data); + // Standard Input typedef int (*pakfire_jail_stdin_callback) (struct pakfire_ctx* ctx, struct pakfire_jail* jail, void* data, int fd); diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index e702428ac..073436fc0 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -148,6 +148,10 @@ struct pakfire_jail_exec { struct pakfire_cgroup* cgroup; struct pakfire_cgroup_stats cgroup_stats; + + // The function to be called once the jail has been set up + int (*callback)(struct pakfire_jail* jail, void* data); + void* data; }; static int pivot_root(const char* new_root, const char* old_root) { @@ -1063,6 +1067,47 @@ static int pakfire_jail_exited(sd_event_source* source, const siginfo_t* si, voi return sd_event_exit(sd_event_source_get_event(source), 0); } +static int pakfire_jail_launch_command(struct pakfire_jail* jail, void* data) { + char** argv = data; + int r; + + // Check if argv is valid + if (!argv || !argv[0]) + return -EINVAL; + + DEBUG(jail->ctx, "Launching command:\n"); + + // Log argv + for (unsigned int i = 0; argv[i]; i++) + DEBUG(jail->ctx, " argv[%u] = %s\n", i, argv[i]); + + // exec() command + r = execvpe(argv[0], argv, jail->env); + if (r < 0) { + // Translate errno into regular exit code + switch (errno) { + case ENOENT: +#if 0 + // Ignore if the command doesn't exist + if (ctx->flags & PAKFIRE_JAIL_NOENT_OK) + r = 0; + else + r = 127; + + break; +#endif + + default: + r = 1; + } + + ERROR(jail->ctx, "Could not execve(%s): %m\n", argv[0]); + } + + // We should not get here + return r; +} + /* Performs the initialisation that needs to happen in the parent part */ @@ -1144,14 +1189,9 @@ static int pakfire_jail_switch_root(struct pakfire_jail* jail, const char* root) return 0; } -static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx, - const char* argv[]) { +static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) { int r; - // Check if we have received a command - if (!argv || !*argv) - return -EINVAL; - // Redirect any logging to our log pipe pakfire_ctx_set_log_callback(jail->ctx, pakfire_jail_log_redirect, ctx); @@ -1330,50 +1370,26 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe return r; DEBUG(jail->ctx, "Child process initialization done\n"); - DEBUG(jail->ctx, "Launching command:\n"); - - // Log argv - for (unsigned int i = 0; argv[i]; i++) - DEBUG(jail->ctx, " argv[%u] = %s\n", i, argv[i]); - // exec() command - r = execvpe(argv[0], (char**)argv, jail->env); - if (r < 0) { - // Translate errno into regular exit code - switch (errno) { - case ENOENT: - // Ignore if the command doesn't exist - if (ctx->flags & PAKFIRE_JAIL_NOENT_OK) - r = 0; - else - r = 127; - - break; - - default: - r = 1; - } - - ERROR(jail->ctx, "Could not execve(%s): %m\n", argv[0]); + // Check if we have a callback + if (!ctx->callback) { + ERROR(jail->ctx, "No callback set\n"); + return 126; } - // We should not get here - return r; + // Call the callback + return ctx->callback(jail, ctx->data); } // Run a command in the jail static int __pakfire_jail_exec(struct pakfire_jail* jail, - const char* argv[], int flags, + pakfire_jail_callback callback, void* data, int flags, pakfire_pty_stdin_callback stdin_callback, void* stdin_data, pakfire_pty_stdout_callback stdout_callback, void* stdout_data, char** output, size_t* output_length) { int pty_flags = 0; int r; - // Check if argv is valid - if (!argv || !argv[0]) - return -EINVAL; - // We cannot have both, an output callback and buffer if (stdout_callback && output) return -EINVAL; @@ -1384,6 +1400,10 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, .flags = flags, .pidfd = -1, + // Callback & Data + .callback = callback, + .data = data, + // Exit Code .exit = -1, }; @@ -1538,7 +1558,7 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, // Child process } else if (ctx.pid == 0) { - r = pakfire_jail_child(jail, &ctx, argv); + r = pakfire_jail_child(jail, &ctx); _exit(r); } @@ -1600,19 +1620,21 @@ ERROR: } 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); + return __pakfire_jail_exec(jail, pakfire_jail_launch_command, 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); + return __pakfire_jail_exec(jail, pakfire_jail_launch_command, argv, flags, + NULL, NULL, NULL, NULL, output, length); } int pakfire_jail_communicate( 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) { - return __pakfire_jail_exec(jail, argv, flags, + return __pakfire_jail_exec(jail, pakfire_jail_launch_command, argv, flags, stdin_callback, stdin_data, stdout_callback, stdout_data, NULL, NULL); }