-/*
- Child 1 is launched in a new mount namespace...
-*/
-static int pakfire_jail_child1(struct pakfire_jail* jail,
- struct pakfire_jail_exec* ctx, const char* argv[]) {
- int r;
-
- // Redirect any logging to our log pipe
- pakfire_ctx_set_log_callback(jail->ctx, pakfire_jail_log_redirect, &ctx->pipes);
-
- CTX_DEBUG(jail->ctx, "First child process launched\n");
-
- const int socket_send = pakfire_jail_get_pipe_to_write(jail, &ctx->socket);
-
- const char* root = pakfire_get_path(jail->pakfire);
-
- // Die with parent
- r = prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);
- if (r) {
- CTX_ERROR(jail->ctx, "Could not configure to die with parent: %s\n", strerror(errno));
- goto ERROR;
- }
-
- // Change mount propagation so that we will receive, but don't propagate back
- r = pakfire_mount_change_propagation(jail->ctx, "/", MS_SLAVE);
- if (r) {
- CTX_ERROR(jail->ctx, "Could not change mount propagation to SLAVE: %s\n", strerror(r));
- goto ERROR;
- }
-
- // Make root a mountpoint in the new mount namespace
- r = pakfire_mount_make_mounpoint(jail->pakfire, root);
- if (r)
- goto ERROR;
-
- // Make everything private
- r = pakfire_mount_change_propagation(jail->ctx, root, MS_PRIVATE);
- if (r) {
- CTX_ERROR(jail->ctx, "Could not change mount propagation to PRIVATE: %s\n", strerror(r));
- goto ERROR;
- }
-
- // Mount everything
- r = pakfire_jail_mount(jail, ctx);
- if (r)
- goto ERROR;
-
- // XXX setup keyring
-
-
-
- // chroot()
- r = pakfire_jail_switch_root(jail, root);
- if (r)
- goto ERROR;
-
- // Change mount propagation so that we will propagate everything down
- r = pakfire_mount_change_propagation(jail->ctx, "/", MS_SHARED);
- if (r) {
- CTX_ERROR(jail->ctx, "Could not change mount propagation to SHARED: %s\n", strerror(r));
- goto ERROR;
- }
-
- // Configure child process
- struct clone_args args = {
- .flags =
- CLONE_NEWCGROUP |
- CLONE_NEWIPC |
- CLONE_NEWNS |
- CLONE_NEWPID |
- CLONE_NEWTIME |
- CLONE_NEWUSER |
- CLONE_NEWUTS |
- CLONE_PIDFD,
- .exit_signal = SIGCHLD,
- .pidfd = (long long unsigned int)&ctx->pidfd2,
- };
-
- // Launch the process into the configured cgroup
- if (ctx->cgroup) {
- args.flags |= CLONE_INTO_CGROUP;
-
- // Clone into this cgroup
- args.cgroup = pakfire_cgroup_fd(ctx->cgroup);
- }
-
- // Setup networking
- if (!pakfire_jail_exec_has_flag(ctx, PAKFIRE_JAIL_HAS_NETWORKING))
- args.flags |= CLONE_NEWNET;
-
- // Fork the second child process
- pid_t pid = clone3(&args, sizeof(args));
- if (pid < 0) {
- CTX_ERROR(jail->ctx, "Could not fork the first child process: %s\n", strerror(errno));
- r = -errno;
- goto ERROR;
-
- // Child process
- } else if (pid == 0) {
- r = pakfire_jail_child2(jail, ctx, argv);
- _exit(r);
- }
-
- // Send the pidfd of the child to the first parent
- r = pakfire_jail_send_fd(jail, socket_send, ctx->pidfd2);
- if (r)
- goto ERROR;
-
-ERROR:
- return r;
-}
-