From 690ff87c7f77eab07607798a12f9f1d5e89c0cc5 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 8 Dec 2023 17:22:43 +0000 Subject: [PATCH] jail: Setup PTY in the master process and add it to the event loop Signed-off-by: Michael Tremer --- src/libpakfire/jail.c | 98 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 96 insertions(+), 2 deletions(-) diff --git a/src/libpakfire/jail.c b/src/libpakfire/jail.c index 6313d894..bdf3f320 100644 --- a/src/libpakfire/jail.c +++ b/src/libpakfire/jail.c @@ -862,12 +862,102 @@ static int pakfire_jail_epoll_add_fd(struct pakfire_jail* jail, int epollfd, int return 0; } +// PTY Forwarding + +static int pakfire_jail_enable_raw_mode(struct pakfire_jail* jail, + struct pakfire_jail_pty_stdio* stdio) { + struct termios raw_attrs; + int r; + + // Fetch all attributes + r = tcgetattr(stdio->fd, &stdio->attrs); + if (r) { + CTX_ERROR(jail->ctx, "Could not fetch terminal attributes from fd %d: %s\n", + stdio->fd, strerror(errno)); + return -errno; + } + + // Copy all attributes + raw_attrs = stdio->attrs; + + // Make it RAW + cfmakeraw(&raw_attrs); + + // Restore the attributes + r = tcsetattr(stdio->fd, TCSANOW, &raw_attrs); + if (r) { + CTX_ERROR(jail->ctx, "Could not restore terminal attributes for fd %d: %s\n", + stdio->fd, strerror(errno)); + return -errno; + } + + return 0; +} + +static void pakfire_jail_restore_attrs(struct pakfire_jail* jail, + const struct pakfire_jail_pty_stdio* stdio) { + int r; + + // Restore the attributes + r = tcsetattr(stdio->fd, TCSANOW, &stdio->attrs); + if (r) { + CTX_DEBUG(jail->ctx, "Could not restore terminal attributes for %d, ignoring: %s\n", + stdio->fd, strerror(errno)); + } +} + static int pakfire_jail_setup_pty_forwarding(struct pakfire_jail* jail, struct pakfire_jail_exec* ctx, const int epollfd, const int fd) { + struct winsize size; + int r; + + CTX_DEBUG(jail->ctx, "Setting up PTY forwarding on fd %d\n", fd); + // Store the file descriptor - ctx->consolefd = fd; + ctx->pty.master.fd = fd; - // XXX TODO + // Configure stdin/stdout + ctx->pty.stdin.fd = STDIN_FILENO; + ctx->pty.stdout.fd = STDOUT_FILENO; + + // Fetch dimensions + r = ioctl(ctx->pty.stdout.fd, TIOCGWINSZ, &size); + if (r) { + CTX_ERROR(jail->ctx, "Failed to determine terminal dimensions: %s\n", strerror(errno)); + return -errno; + } + + // Set dimensions + r = ioctl(ctx->pty.master.fd, TIOCSWINSZ, &size); + if (r) { + CTX_ERROR(jail->ctx, "Failed setting dimensions: %s\n", strerror(errno)); + return -errno; + } + + // Enable RAW mode on standard input + r = pakfire_jail_enable_raw_mode(jail, &ctx->pty.stdin); + if (r) + return r; + + // Enable RAW mode on standard output + r = pakfire_jail_enable_raw_mode(jail, &ctx->pty.stdout); + if (r) + return r; + + // Add the master to the event loop + r = pakfire_jail_epoll_add_fd(jail, epollfd, ctx->pty.master.fd, EPOLLIN|EPOLLOUT|EPOLLET); + if (r) + return r; + + // Add standard input to the event loop + r = pakfire_jail_epoll_add_fd(jail, epollfd, ctx->pty.stdin.fd, EPOLLIN|EPOLLET); + if (r) + return r; + + // Add standard output to the event loop + r = pakfire_jail_epoll_add_fd(jail, epollfd, ctx->pty.stdout.fd, EPOLLOUT|EPOLLET); + if (r) + return r; return 0; } @@ -1129,6 +1219,10 @@ ERROR: if (timerfd >= 0) close(timerfd); + // Restore any changed terminal attributes + pakfire_jail_restore_attrs(jail, &ctx->pty.stdin); + pakfire_jail_restore_attrs(jail, &ctx->pty.stdout); + return r; } -- 2.39.2