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);
}
// 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;
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)) {
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