]> git.ipfire.org Git - people/ms/pakfire.git/blobdiff - src/libpakfire/jail.c
jail: Commit some disabled code to set up a PTY
[people/ms/pakfire.git] / src / libpakfire / jail.c
index dd24b7449a1d5888a9412d0f81beb8895c49e8ee..472fcb2ac33f31e98cdb38ded3b51258cf98bbc4 100644 (file)
@@ -35,7 +35,6 @@
 #include <sys/personality.h>
 #include <sys/prctl.h>
 #include <sys/resource.h>
-#include <sys/signalfd.h>
 #include <sys/timerfd.h>
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -176,6 +175,10 @@ struct pakfire_jail_exec {
 
        struct pakfire_cgroup* cgroup;
        struct pakfire_cgroup_stats cgroup_stats;
+
+       // Console
+       char console[PATH_MAX];
+       int consolefd;
 };
 
 static int clone3(struct clone_args* args, size_t size) {
@@ -530,34 +533,6 @@ ERROR:
        return -1;
 }
 
-// Signals
-
-#if 0
-static int pakfire_jail_handle_signals(struct pakfire_jail* jail) {
-       sigset_t mask;
-       int r;
-
-       sigemptyset(&mask);
-       sigaddset(&mask, SIGINT);
-
-       // Block signals
-       r = sigprocmask(SIG_BLOCK, &mask, NULL);
-       if (r < 0) {
-               ERROR(jail->pakfire, "Failed to block signals: %m\n");
-               return r;
-       }
-
-       // Create a file descriptor
-       r = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
-       if (r < 0) {
-               ERROR(jail->pakfire, "Failed to create signalfd: %m\n");
-               return r;
-       }
-
-       return r;
-}
-#endif
-
 /*
        This function replaces any logging in the child process.
 
@@ -921,11 +896,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
        const int log_DEBUG = pakfire_jail_get_pipe_to_read(jail, &ctx->pipes.log_DEBUG);
 #endif /* ENABLE_DEBUG */
 
-#if 0
-       // Signals
-       const int signalfd = pakfire_jail_handle_signals(jail);
-#endif
-
        // Make a list of all file descriptors we are interested in
        const struct pakfire_wait_fds {
                const int fd;
@@ -944,11 +914,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                // Child Processes
                { ctx->pidfd1, EPOLLIN },
 
-#if 0
-               // Signals
-               { signafd, EPOLLIN },
-#endif
-
                // Log Pipes
                { log_INFO, EPOLLIN },
                { log_ERROR, EPOLLIN },
@@ -1067,39 +1032,6 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                                        // There is nothing else to do
                                        continue;
 
-#if 0
-                               // Handle signals
-                               } else if (fd == signalfd) {
-                                       // Read the signal
-                                       r = read(signalfd, &siginfo, sizeof(siginfo));
-                                       if (r < 1) {
-                                               ERROR(jail->pakfire, "Could not read signal: %m\n");
-                                               goto ERROR;
-                                       }
-
-                                       DEBUG(jail->pakfire, "Received signal %u\n", siginfo.ssi_signo);
-
-                                       // Handle signals
-                                       switch (siginfo.ssi_signo) {
-                                               // Pass SIGINT down to the child process
-                                               case SIGINT:
-                                                       r = pidfd_send_signal(pidfd, siginfo.ssi_signo, NULL, 0);
-                                                       if (r) {
-                                                               ERROR(jail->pakfire, "Could not send signal to process: %m\n");
-                                                               goto ERROR;
-                                                       }
-                                                       break;
-
-                                               default:
-                                                       ERROR(jail->pakfire, "Received unhandled signal %u\n",
-                                                               siginfo.ssi_signo);
-                                                       break;
-                                       }
-
-                                       // Don't fall through to log processing
-                                       continue;
-#endif
-
                                // Handle socket messages
                                } else if (fd == socket_recv) {
                                        // Receive the FD of the second child process
@@ -1219,10 +1151,6 @@ ERROR:
                close(epollfd);
        if (timerfd >= 0)
                close(timerfd);
-#if 0
-       if (signalfd >= 0)
-               close(signalfd);
-#endif
 
        return r;
 }
@@ -1527,7 +1455,17 @@ static int pakfire_jail_mount(struct pakfire_jail* jail, struct pakfire_jail_exe
                flags |= PAKFIRE_MOUNT_LOOP_DEVICES;
 
        // Mount all default stuff
-       r = pakfire_mount_all(jail->pakfire, flags);
+       r = pakfire_mount_all(jail->pakfire, PAKFIRE_MNTNS_OUTER, flags);
+       if (r)
+               return r;
+
+       // Populate /dev
+       r = pakfire_populate_dev(jail->pakfire, flags);
+       if (r)
+               return r;
+
+       // Mount the interpreter (if needed)
+       r = pakfire_mount_interpreter(jail->pakfire);
        if (r)
                return r;
 
@@ -1549,9 +1487,6 @@ static int pakfire_jail_mount(struct pakfire_jail* jail, struct pakfire_jail_exe
                        return r;
        }
 
-       // Log all mountpoints
-       pakfire_mount_list(jail->pakfire);
-
        return 0;
 }
 
@@ -1710,38 +1645,19 @@ static int pakfire_jail_setup_gid_mapping(struct pakfire_jail* jail, pid_t pid)
 
 static int pakfire_jail_setgroups(struct pakfire_jail* jail, pid_t pid) {
        char path[PATH_MAX];
-       int r = 1;
+       int r;
 
        // Make path
        r = pakfire_string_format(path, "/proc/%d/setgroups", pid);
        if (r)
                return r;
 
-       // Open file for writing
-       FILE* f = fopen(path, "w");
-       if (!f) {
-               ERROR(jail->pakfire, "Could not open %s for writing: %m\n", path);
-               goto ERROR;
-       }
-
-       // Write content
-       int bytes_written = fprintf(f, "deny\n");
-       if (bytes_written <= 0) {
-               ERROR(jail->pakfire, "Could not write to %s: %m\n", path);
-               goto ERROR;
-       }
-
-       r = fclose(f);
-       f = NULL;
+       r = pakfire_file_write(jail->pakfire, path, 0, 0, 0, "deny\n");
        if (r) {
-               ERROR(jail->pakfire, "Could not close %s: %m\n", path);
-               goto ERROR;
+               CTX_ERROR(jail->ctx, "Could not set setgroups to deny: %s\n", strerror(errno));
+               r = -errno;
        }
 
-ERROR:
-       if (f)
-               fclose(f);
-
        return r;
 }
 
@@ -1809,6 +1725,31 @@ static int pakfire_jail_switch_root(struct pakfire_jail* jail, const char* root)
        return 0;
 }
 
+#if 0
+static int pakfire_jail_open_pty(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) {
+       int r;
+
+       // Allocate a new PTY
+       ctx->consolefd = posix_openpt(O_RDWR|O_NONBLOCK|O_NOCTTY|O_CLOEXEC);
+       if (ctx->consolefd < 0)
+               return -errno;
+
+       // Fetch the path
+       r = ptsname_r(ctx->consolefd, ctx->console, sizeof(ctx->console));
+       if (r)
+               return -r;
+
+       CTX_DEBUG(jail->ctx, "Allocated console at %s (%d)\n", ctx->console, ctx->consolefd);
+
+       // Create a symlink
+       r = pakfire_symlink(jail->ctx, "/dev/console", ctx->console);
+       if (r)
+               return r;
+
+       return r;
+}
+#endif
+
 /*
        Called by the parent that sets up the second child process...
 */
@@ -1862,13 +1803,6 @@ static int pakfire_jail_child2(struct pakfire_jail* jail,
 
        CTX_DEBUG(jail->ctx, "Launched child process in jail with PID %d\n", pid);
 
-       // 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: %m\n");
-               return 126;
-       }
-
        // Make this process dumpable
        r = prctl (PR_SET_DUMPABLE, 1, 0, 0, 0);
        if (r) {
@@ -1899,18 +1833,42 @@ static int pakfire_jail_child2(struct pakfire_jail* jail,
        DEBUG(jail->pakfire, "  UID: %u (effective %u)\n", uid, euid);
        DEBUG(jail->pakfire, "  GID: %u (effective %u)\n", gid, egid);
 
+       // Log all mountpoints
+       pakfire_mount_list(jail->ctx);
+
        // Fail if we are not PID 1
        if (pid != 1) {
                CTX_ERROR(jail->ctx, "Child process is not PID 1\n");
-               //return 126;
+               return 126;
        }
 
        // Fail if we are not running as root
        if (uid || gid || euid || egid) {
                ERROR(jail->pakfire, "Child process is not running as root\n");
-               //return 126;
+               return 126;
+       }
+
+       // Mount all default stuff
+       r = pakfire_mount_all(jail->pakfire, PAKFIRE_MNTNS_INNER, 0);
+       if (r)
+               return 126;
+
+#if 0
+       // Create a new session
+       r = setsid();
+       if (r < 0) {
+               CTX_ERROR(jail->ctx, "Could not create a new session: %s\n", strerror(errno));
+               return 126;
        }
 
+       // Allocate a new PTY
+       r = pakfire_jail_open_pty(jail, ctx);
+       if (r) {
+               CTX_ERROR(jail->ctx, "Could not allocate a new PTY: %s\n", strerror(-r));
+               return 126;
+       }
+#endif
+
        const char* arch = pakfire_get_effective_arch(jail->pakfire);
 
        // Set personality
@@ -2082,6 +2040,10 @@ static int pakfire_jail_child1(struct pakfire_jail* jail,
        if (r)
                goto ERROR;
 
+       // XXX setup keyring
+
+
+
        // chroot()
        r = pakfire_jail_switch_root(jail, root);
        if (r)
@@ -2306,17 +2268,9 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[],
 ERROR:
        // Destroy the temporary cgroup (if any)
        if (ctx.cgroup) {
-#if 0
-               // XXX this is currently disabled because it overwrites r
                // Read cgroup stats
-               r = pakfire_cgroup_stat(ctx.cgroup, &ctx.cgroup_stats);
-               if (r) {
-                       ERROR(jail->pakfire, "Could not read cgroup stats: %m\n");
-               } else {
-                       pakfire_cgroup_stat_dump(ctx.cgroup, &ctx.cgroup_stats);
-               }
-#endif
-
+               pakfire_cgroup_stat(ctx.cgroup, &ctx.cgroup_stats);
+               pakfire_cgroup_stat_dump(ctx.cgroup, &ctx.cgroup_stats);
                pakfire_cgroup_destroy(ctx.cgroup);
                pakfire_cgroup_unref(ctx.cgroup);
        }