]> git.ipfire.org Git - pakfire.git/commitdiff
jail: Have the child process allocate a new PTY
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 8 Dec 2023 15:47:20 +0000 (15:47 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 8 Dec 2023 15:47:20 +0000 (15:47 +0000)
The master file descriptor is being sent to the parent process.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/jail.c

index ed1223d65153953694d045539bfa6349db915cf9..264664ea819badff2ad354ceaf967b6693d56633 100644 (file)
@@ -838,6 +838,16 @@ static int pakfire_jail_epoll_add_fd(struct pakfire_jail* jail, int epollfd, int
        return 0;
 }
 
+static int pakfire_jail_setup_pty_forwarding(struct pakfire_jail* jail,
+               struct pakfire_jail_exec* ctx, const int epollfd, const int fd) {
+       // Store the file descriptor
+       ctx->consolefd = fd;
+
+       // XXX TODO
+
+       return 0;
+}
+
 static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx) {
        int epollfd = -1;
        struct epoll_event events[EPOLL_MAX_EVENTS];
@@ -1036,7 +1046,14 @@ static int pakfire_jail_wait(struct pakfire_jail* jail, struct pakfire_jail_exec
                                        if (r)
                                                goto ERROR;
 
-                                       // XXX Do something with the file descriptor
+                                       // Setup PTY forwarding
+                                       if (ctx->consolefd < 0) {
+                                               r = pakfire_jail_setup_pty_forwarding(jail, ctx, epollfd, fd);
+                                               if (r) {
+                                                       CTX_ERROR(jail->ctx, "Failed setting up PTY forwarding: %s\n", strerror(-r));
+                                                       goto ERROR;
+                                               }
+                                       }
 
                                        // Don't fall through to log processing
                                        continue;
@@ -1693,7 +1710,6 @@ 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;
 
@@ -1709,14 +1725,15 @@ static int pakfire_jail_open_pty(struct pakfire_jail* jail, struct pakfire_jail_
 
        CTX_DEBUG(jail->ctx, "Allocated console at %s (%d)\n", ctx->console, ctx->consolefd);
 
+#if 0
        // Create a symlink
        r = pakfire_symlink(jail->ctx, "/dev/console", ctx->console);
        if (r)
                return r;
+#endif
 
        return r;
 }
-#endif
 
 static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx,
                const char* argv[]) {
@@ -1782,27 +1799,13 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe
                return 126;
        }
 
+       const int socket_send = pakfire_jail_get_pipe_to_write(jail, &ctx->socket);
+
        // 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* root = pakfire_get_path(jail->pakfire);
        const char* arch = pakfire_get_effective_arch(jail->pakfire);
 
@@ -1862,6 +1865,36 @@ static int pakfire_jail_child(struct pakfire_jail* jail, struct pakfire_jail_exe
                }
        }
 
+#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 r;
+       }
+#endif
+
+       // 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 r;
+       }
+
+       // Send the PTY master to the parent process
+       r = pakfire_jail_send_fd(jail, socket_send, ctx->consolefd);
+       if (r) {
+               CTX_ERROR(jail->ctx, "Failed sending the PTY master to the parent: %s\n", strerror(-r));
+               return r;
+       }
+
+       // Close the master of the PTY
+       close(ctx->consolefd);
+       ctx->consolefd = -1;
+
+       // Close the socket
+       close(socket_send);
+
        // Close other end of log pipes
        close(ctx->pipes.log_INFO[0]);
        close(ctx->pipes.log_ERROR[0]);
@@ -1995,6 +2028,8 @@ static int __pakfire_jail_exec(struct pakfire_jail* jail, const char* argv[],
                },
 
                .pidfd = -1,
+
+               .consolefd = -1,
        };
 
        DEBUG(jail->pakfire, "Executing jail...\n");
@@ -2162,6 +2197,8 @@ ERROR:
        pakfire_jail_close_pipe(jail, ctx.pipes.stderr);
        if (ctx.pidfd >= 0)
                close(ctx.pidfd);
+       if (ctx.consolefd >= 0)
+               close(ctx.consolefd);
        pakfire_jail_close_pipe(jail, ctx.pipes.log_INFO);
        pakfire_jail_close_pipe(jail, ctx.pipes.log_ERROR);
 #ifdef ENABLE_DEBUG