subproc: kill a process once in the -Ml mode once the TCP connection has ended
authorRobert Swiecki <robert@swiecki.net>
Sun, 30 Aug 2020 20:02:08 +0000 (22:02 +0200)
committerRobert Swiecki <robert@swiecki.net>
Sun, 30 Aug 2020 20:02:08 +0000 (22:02 +0200)
nsjail.cc
nsjail.h
subproc.cc
subproc.h

index 8d57b8637c1e6b0cc122bcef0b7a425d5cc243b0..52f85f6a8ba985621c55a7841028ae4e9db062d7 100644 (file)
--- a/nsjail.cc
+++ b/nsjail.cc
@@ -200,6 +200,9 @@ static bool pipeTraffic(nsjconf_t* nsjconf, int listenfd) {
                                close(nsjconf->pipes[pipe_no].sock_fd);
                                close(nsjconf->pipes[pipe_no].pipe_in);
                                close(nsjconf->pipes[pipe_no].pipe_out);
+                               if (nsjconf->pipes[pipe_no].pid > 0) {
+                                       kill(nsjconf->pipes[pipe_no].pid, SIGKILL);
+                               }
                                nsjconf->pipes[pipe_no] = {};
                        }
                }
@@ -237,12 +240,14 @@ static int listenMode(nsjconf_t* nsjconf) {
                                        PLOG_E("pipe");
                                        continue;
                                }
+                               pid_t pid =
+                                   subproc::runChild(nsjconf, connfd, in[0], out[1], out[1]);
                                nsjconf->pipes.push_back({
                                    .sock_fd = connfd,
                                    .pipe_in = in[1],
                                    .pipe_out = out[0],
+                                   .pid = pid,
                                });
-                               subproc::runChild(nsjconf, connfd, in[0], out[1], out[1]);
                                close(in[0]);
                                close(out[1]);
                        }
@@ -253,8 +258,8 @@ static int listenMode(nsjconf_t* nsjconf) {
 
 static int standaloneMode(nsjconf_t* nsjconf) {
        for (;;) {
-               if (!subproc::runChild(
-                       nsjconf, /* netfd= */ -1, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO)) {
+               if (subproc::runChild(nsjconf, /* netfd= */ -1, STDIN_FILENO, STDOUT_FILENO,
+                       STDERR_FILENO) == -1) {
                        LOG_E("Couldn't launch the child process");
                        return 0xff;
                }
index 8200486166de67e4857ff99f7dac90ce28bc73c1..fda3392bc3249a3b5f55f50becef1171a4a1c72b 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -86,6 +86,7 @@ struct pipemap_t {
        int sock_fd;
        int pipe_in;
        int pipe_out;
+       pid_t pid;
        bool operator==(const pipemap_t& o) {
                return sock_fd == o.sock_fd && pipe_in == o.pipe_in && pipe_out == o.pipe_out;
        }
index 2f1c5cd03f33f388cb02bad4c3ddb288b4213e74..6da7a515eb13c19c3e25115e1cc482502336f877 100644 (file)
@@ -408,9 +408,9 @@ static bool initParent(nsjconf_t* nsjconf, pid_t pid, int pipefd) {
        return true;
 }
 
-bool runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err) {
+pid_t runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err) {
        if (!net::limitConns(nsjconf, netfd)) {
-               return true;
+               return 0;
        }
        unsigned long flags = 0UL;
        flags |= (nsjconf->clone_newnet ? CLONE_NEWNET : 0);
@@ -435,7 +435,7 @@ bool runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err)
        int sv[2];
        if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) == -1) {
                PLOG_E("socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC) failed");
-               return false;
+               return -1;
        }
        int child_fd = sv[0];
        int parent_fd = sv[1];
@@ -463,13 +463,13 @@ bool runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err)
                    "kernel.unprivileged_userns_clone sysctl",
                    cloneFlagsToStr(flags).c_str());
                close(parent_fd);
-               return false;
+               return -1;
        }
        addProc(nsjconf, pid, netfd);
 
        if (!initParent(nsjconf, pid, parent_fd)) {
                close(parent_fd);
-               return false;
+               return -1;
        }
 
        char rcvChar;
@@ -477,11 +477,11 @@ bool runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err)
            rcvChar == kSubprocErrorChar) {
                LOG_W("Received error message from the child process before it has been executed");
                close(parent_fd);
-               return false;
+               return -1;
        }
 
        close(parent_fd);
-       return true;
+       return pid;
 }
 
 /*
index c33991fe60e0c9834afa26d9266c5d9a3123396d..5497abdf87c514d09842c3430af5d781973f8968 100644 (file)
--- a/subproc.h
+++ b/subproc.h
@@ -33,7 +33,8 @@
 
 namespace subproc {
 
-bool runChild(nsjconf_t* nsjconf, int listen_fd, int fd_in, int fd_out, int fd_err);
+/* 0 - network connection limit reached, -1 - error */
+pid_t runChild(nsjconf_t* nsjconf, int listen_fd, int fd_in, int fd_out, int fd_err);
 int countProc(nsjconf_t* nsjconf);
 void displayProc(nsjconf_t* nsjconf);
 void killAndReapAll(nsjconf_t* nsjconf);