diff --git a/system/src/riju-pty.c b/system/src/riju-pty.c index 5f214b0..8dc4059 100644 --- a/system/src/riju-pty.c +++ b/system/src/riju-pty.c @@ -3,9 +3,11 @@ #include #include #include +#include #include #include #include +#include #include #include #include @@ -22,8 +24,12 @@ void die_with_usage() { die("usage: riju-pty [-f] CMDLINE..."); } struct termios orig_termios; +bool do_restore_tty = true; + void restore_tty() { + if (!do_restore_tty) + return; if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios) < 0) die("tcsetattr failed"); } @@ -57,11 +63,7 @@ int main(int argc, char **argv) if (tcgetattr(STDIN_FILENO, &orig_termios) < 0) die("tcgetattr failed"); struct termios raw = orig_termios; - // https://viewsourcecode.org/snaptoken/kilo/02.enteringRawMode.html - raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - raw.c_oflag &= ~(OPOST); - raw.c_cflag |= (CS8); - raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); + cfmakeraw(&raw); if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw) < 0) die("tcsetattr failed"); if (atexit(restore_tty) < 0) @@ -70,10 +72,15 @@ int main(int argc, char **argv) if (errno != ENOTTY) die("isatty failed"); } + pid_t orig_ppid = getpid(); pid_t exec_pid = fork(); if (exec_pid < 0) die("fork failed"); else if (exec_pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + die("prctl failed"); + if (getppid() != orig_ppid) + exit(EXIT_FAILURE); if (!no_pty) { close(pty_master_fd); if (setsid() < 0) @@ -93,9 +100,7 @@ int main(int argc, char **argv) execvp(argv[0], &argv[0]); die("execvp failed"); } - if (setpgrp() < 0) - die("setpgrp failed"); - int pid = no_pty ? 1 : fork(); + pid_t pid = no_pty ? 1 : fork(); if (pid < 0) die("fork failed"); else if (pid > 0) { @@ -103,19 +108,29 @@ int main(int argc, char **argv) if (waitpid(exec_pid, &wstatus, 0) != exec_pid) die("waitpid failed"); if (!no_pty) { - if (signal(SIGTERM, SIG_IGN) == SIG_ERR) - die("signal failed"); - if (kill(0, SIGTERM) < 0) + if (kill(-pid, SIGTERM) < 0) die("kill failed"); } return WEXITSTATUS(wstatus); } + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + die("prctl failed"); + if (getppid() != orig_ppid) + exit(EXIT_FAILURE); + do_restore_tty = false; + if (setpgrp() < 0) + die("setpgrp failed"); char buf[1024]; int len, len_written; + orig_ppid = getpid(); pid = fork(); if (pid < 0) die("fork failed"); else if (pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + die("prctl failed"); + if (getppid() != orig_ppid) + exit(EXIT_FAILURE); while ((len = read(STDIN_FILENO, buf, 1024)) > 0) { char *ptr = buf; while (len > 0) { diff --git a/system/src/riju-system-privileged.c b/system/src/riju-system-privileged.c index e5ca3bf..0ebd8c1 100644 --- a/system/src/riju-system-privileged.c +++ b/system/src/riju-system-privileged.c @@ -1,3 +1,4 @@ +#include #define _GNU_SOURCE #include #include @@ -8,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -174,10 +176,15 @@ void session(char *uuid, char *lang, char *imageHash) die("asprintf failed"); if (mknod(fifo, 0600 | S_IFIFO, 0) < 0) die("mknod failed"); + pid_t orig_ppid = getpid(); pid_t pid = fork(); if (pid < 0) die("fork failed"); else if (pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + die("prctl failed"); + if (getppid() != orig_ppid) + exit(EXIT_FAILURE); char *argv[] = { "docker", "run", @@ -253,27 +260,18 @@ void session(char *uuid, char *lang, char *imageHash) } if (signal(SIGALRM, SIG_IGN) == SIG_ERR) die("signal failed"); - pid = fork(); - if (pid < 0) - die("fork failed"); - else if (pid == 0) { - struct timespec ts_1s; - ts_1s.tv_sec = 1; - ts_1s.tv_nsec = 0; - while (1) { - static const char ok[] = "ping\n"; - if (write(fd, ok, sizeof(ok) / sizeof(char)) != sizeof(ok) / sizeof(char)) - die("write failed"); - int rv = nanosleep(&ts_1s, NULL); - if (rv != 0 && errno != EINTR) - die("nanosleep failed"); - } - } printf("riju: container ready\n"); // magic string - if (waitpid(pid, NULL, 0) <= 0) - die("waitpid failed"); - if (close(fd) < 0) - die("close failed"); + struct timespec ts_1s; + ts_1s.tv_sec = 1; + ts_1s.tv_nsec = 0; + while (1) { + static const char ok[] = "ping\n"; + if (write(fd, ok, sizeof(ok) / sizeof(char)) != sizeof(ok) / sizeof(char)) + die("write failed"); + int rv = nanosleep(&ts_1s, NULL); + if (rv != 0 && errno != EINTR) + die("nanosleep failed"); + } } void exec(char *uuid, int argc, char **cmdline, bool pty) @@ -313,16 +311,25 @@ void exec(char *uuid, int argc, char **cmdline, bool pty) struct timespec ts_10ms; ts_10ms.tv_sec = 0; ts_10ms.tv_nsec = 1000 * 1000 * 10; - pid_t input_pid = fork(), output_pid; - if (input_pid < 0) + pid_t orig_ppid = getpid(); + pid_t pid = fork(); + if (pid < 0) die("fork failed"); - else if (input_pid == 0) { + else if (pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + die("prctl failed"); + if (getppid() != orig_ppid) + exit(EXIT_FAILURE); dataFIFO = inputFIFO; } else { - output_pid = fork(); - if (output_pid < 0) + pid = fork(); + if (pid < 0) die("fork failed"); - else if (output_pid == 0) { + else if (pid == 0) { + if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) + die("prctl failed"); + if (getppid() != orig_ppid) + exit(EXIT_FAILURE); dataFIFO = outputFIFO; } else { dataFIFO = statusFIFO; @@ -392,10 +399,6 @@ void exec(char *uuid, int argc, char **cmdline, bool pty) long status = strtol(line, &endptr, 10); if (*endptr != '\n') die("strtol failed"); - if (kill(input_pid, SIGTERM) < 0) - die("kill failed"); - if (kill(output_pid, SIGTERM) < 0) - die("kill failed"); exit(status); } }