From: Michael Tremer Date: Mon, 29 Mar 2021 22:46:45 +0000 (+0000) Subject: execute: Use clone3() X-Git-Tag: 0.9.28~1285^2~452 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=45d05adf28378abfaa6d12ec35a3242b06f55d36;p=pakfire.git execute: Use clone3() This is a new syscall which does not come with a glibc wrapper. This makes it slightly uncomfortable to use, but it brings us new features that we want to use. Signed-off-by: Michael Tremer --- diff --git a/src/libpakfire/execute.c b/src/libpakfire/execute.c index 8ba178d54..078b20387 100644 --- a/src/libpakfire/execute.c +++ b/src/libpakfire/execute.c @@ -61,6 +61,24 @@ struct pakfire_execute_buffer { size_t used; }; +#ifndef __NR_clone3 +#define __NR_clone3 435 +#endif + +struct clone_args { + uint64_t flags; + uint64_t pidfd; + uint64_t child_tid; + uint64_t parent_tid; + uint64_t exit_signal; + uint64_t stack; + uint64_t stack_size; + uint64_t tls; + uint64_t set_tid; + uint64_t set_tid_size; + uint64_t cgroup; +}; + static int pakfire_execute_buffer_is_full(const struct pakfire_execute_buffer* buffer) { return (sizeof(buffer->data) == buffer->used); } @@ -337,9 +355,6 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en // Make cgroup name snprintf(env.cgroup, sizeof(env.cgroup) - 1, "%s", "pakfire/execute-XXXXXX"); - // Allocate stack - char stack[4096]; - // argv is invalid if (!argv || !argv[0]) return -EINVAL; @@ -350,13 +365,20 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en if (!logging_callback) logging_callback = &default_logging_callback; - // Configure the new namespace - int cflags = CLONE_VFORK | SIGCHLD | CLONE_NEWIPC | CLONE_NEWNS | CLONE_NEWUTS - | CLONE_NEWCGROUP; + // Configure child process + struct clone_args args = { + .flags = + CLONE_VFORK | + CLONE_NEWCGROUP | + CLONE_NEWIPC | + CLONE_NEWNS | + CLONE_NEWUTS, + .exit_signal = SIGCHLD, + }; // Enable network? if (!(flags & PAKFIRE_EXECUTE_ENABLE_NETWORK)) - cflags |= CLONE_NEWNET; + args.flags |= CLONE_NEWNET; // Make some file descriptors for stdout & stderr if (!(flags & PAKFIRE_EXECUTE_INTERACTIVE)) { @@ -381,10 +403,15 @@ PAKFIRE_EXPORT int pakfire_execute(Pakfire pakfire, const char* argv[], char* en goto ERROR; // Fork this process - pid_t pid = clone(pakfire_execute_fork, stack + sizeof(stack), cflags, &env); + pid_t pid = syscall(__NR_clone3, &args, sizeof(args)); if (pid < 0) { ERROR(pakfire, "Could not fork: %s\n", strerror(errno)); return -errno; + + // Child process + } else if (pid == 0) { + r = pakfire_execute_fork(&env); + exit(r); } // Attach the process to the cgroup