Hello community,

here is the log from the commit of package nsjail for openSUSE:Factory checked 
in at 2020-07-29 17:21:56
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nsjail (Old)
 and      /work/SRC/openSUSE:Factory/.nsjail.new.3592 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nsjail"

Wed Jul 29 17:21:56 2020 rev:7 rq:823401 version:3.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/nsjail/nsjail.changes    2020-06-19 
17:24:28.512083420 +0200
+++ /work/SRC/openSUSE:Factory/.nsjail.new.3592/nsjail.changes  2020-07-29 
17:23:47.924730688 +0200
@@ -1,0 +2,11 @@
+Tue Jul 28 09:10:57 UTC 2020 - Paolo Stivanin <i...@paolostivanin.com>
+
+- Update to 3.0:
+  * the TCP proxy mode is a socketpair proxy now
+  * fixes for some configs/ (e.g. for xchat and for znc)
+  * new clone option recognized (CLONE_NEWPID)
+  * fixed max_conns_per_ip
+  * clarification of units for cgroups_mem_max
+- Remove remove_werror.patch
+
+-------------------------------------------------------------------

Old:
----
  nsjail-2.9.tar.gz
  remove_werror.patch

New:
----
  nsjail-3.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nsjail.spec ++++++
--- /var/tmp/diff_new_pack.Wd0cjW/_old  2020-07-29 17:23:48.656731318 +0200
+++ /var/tmp/diff_new_pack.Wd0cjW/_new  2020-07-29 17:23:48.660731321 +0200
@@ -17,15 +17,14 @@
 
 
 Name:           nsjail
-Version:        2.9
+Version:        3.0
 Release:        0
 Summary:        A light-weight process isolation tool
 License:        Apache-2.0
 Group:          System/GUI/Other
 URL:            https://nsjail.com
-Source0:        nsjail-%{version}.tar.gz
+Source0:        
https://github.com/google/nsjail/archive/%{version}.tar.gz#/nsjail-%{version}.tar.gz
 Source1:        kafel.tar.gz
-Patch0:         remove_werror.patch
 BuildRequires:  autoconf
 BuildRequires:  bison
 BuildRequires:  flex
@@ -44,7 +43,6 @@
 
 %prep
 %setup -qa1
-%patch0 -p1
 
 %build
 %define _lto_cflags %{nil}
@@ -55,9 +53,23 @@
 %install
 mkdir -p %{buildroot}/%{_bindir}/
 cp nsjail %{buildroot}/%{_bindir}/
+mkdir -p %{buildroot}/%{_sysconfdir}/%{name}
+install -m 644 configs/*.cfg %{buildroot}/%{_sysconfdir}/%{name}
 
 %files
 %license LICENSE
 %{_bindir}/nsjail
+%{_sysconfdir}/%{name}
+%config %{_sysconfdir}/%{name}/xchat-with-net.cfg
+%config %{_sysconfdir}/%{name}/znc-with-net.cfg
+%config %{_sysconfdir}/%{name}/apache.cfg
+%config %{_sysconfdir}/%{name}/bash-with-fake-geteuid.cfg
+%config %{_sysconfdir}/%{name}/demo-dont-use-chrome-with-net.cfg
+%config %{_sysconfdir}/%{name}/firefox-with-cloned-net.cfg
+%config %{_sysconfdir}/%{name}/firefox-with-net.cfg
+%config %{_sysconfdir}/%{name}/home-documents-with-xorg-no-net.cfg
+%config %{_sysconfdir}/%{name}/imagemagick-convert.cfg
+%config %{_sysconfdir}/%{name}/static-busybox-with-execveat.cfg
+%config %{_sysconfdir}/%{name}/tomcat8.cfg
 
 %changelog

++++++ nsjail-2.9.tar.gz -> nsjail-3.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/.github/workflows/dockerpush.yml 
new/nsjail-3.0/.github/workflows/dockerpush.yml
--- old/nsjail-2.9/.github/workflows/dockerpush.yml     1970-01-01 
01:00:00.000000000 +0100
+++ new/nsjail-3.0/.github/workflows/dockerpush.yml     2020-07-23 
00:09:23.000000000 +0200
@@ -0,0 +1,66 @@
+name: Docker
+
+on:
+  push:
+    # Publish `master` as Docker `latest` image.
+    branches:
+      - master
+
+    # Publish `v1.2.3` tags as releases.
+    tags:
+      - v*
+
+  # Run tests for any PRs.
+  pull_request:
+
+env:
+  IMAGE_NAME: nsjail
+
+jobs:
+  # Run tests.
+  # See also https://docs.docker.com/docker-hub/builds/automated-testing/
+  test:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Run tests
+        run: docker build . --file Dockerfile
+
+  # Push image to GitHub Package Registry.
+  # See also https://docs.docker.com/docker-hub/builds/
+  push:
+    # Ensure test job passes before pushing image.
+    needs: test
+
+    runs-on: ubuntu-latest
+    if: github.event_name == 'push'
+
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Build image
+        run: docker build . --file Dockerfile --tag image
+
+      - name: Log into registry
+        run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login 
docker.pkg.github.com -u ${{ github.actor }} --password-stdin
+
+      - name: Push image
+        run: |
+          IMAGE_ID=docker.pkg.github.com/${{ github.repository }}/$IMAGE_NAME
+
+          # Strip git ref prefix from version
+          VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,')
+
+          # Strip "v" prefix from tag name
+          [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo 
$VERSION | sed -e 's/^v//')
+
+          # Use Docker `latest` tag convention
+          [ "$VERSION" == "master" ] && VERSION=latest
+
+          echo IMAGE_ID=$IMAGE_ID
+          echo VERSION=$VERSION
+
+          docker tag image $IMAGE_ID:$VERSION
+          docker push $IMAGE_ID:$VERSION
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/Dockerfile new/nsjail-3.0/Dockerfile
--- old/nsjail-2.9/Dockerfile   2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/Dockerfile   2020-07-23 00:09:23.000000000 +0200
@@ -1,4 +1,4 @@
-FROM ubuntu:16.04
+FROM ubuntu:18.04
 
 RUN apt-get -y update && apt-get install -y \
     autoconf \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/Makefile new/nsjail-3.0/Makefile
--- old/nsjail-2.9/Makefile     2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/Makefile     2020-07-23 00:09:23.000000000 +0200
@@ -31,7 +31,7 @@
        -Wall -Wextra -Werror \
        -Ikafel/include
 
-CXXFLAGS += $(COMMON_FLAGS) $(shell pkg-config --cflags protobuf) \
+CXXFLAGS += $(USER_DEFINES) $(COMMON_FLAGS) $(shell pkg-config --cflags 
protobuf) \
        -std=c++11 -fno-exceptions -Wno-unused -Wno-unused-parameter
 LDFLAGS += -pie -Wl,-z,noexecstack -lpthread $(shell pkg-config --libs 
protobuf)
 
@@ -69,10 +69,14 @@
 endif
        $(CXX) -o $(BIN) $(OBJS) $(LIBS) $(LDFLAGS)
 
-kafel/libkafel.a:
+.PHONY: kafel_init
+kafel_init:
 ifeq ("$(wildcard kafel/Makefile)","")
        git submodule update --init
 endif
+
+kafel/include/kafel.h: kafel_init
+kafel/libkafel.a: kafel_init
        $(MAKE) -C kafel
 
 # Sequence of proto deps, which doesn't fit automatic make rules
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/README.md new/nsjail-3.0/README.md
--- old/nsjail-2.9/README.md    2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/README.md    2020-07-23 00:09:23.000000000 +0200
@@ -357,9 +357,9 @@
  --rw 
        Mount chroot dir (/) R/W (default: R/O)
  --user|-u VALUE
-       Username/uid of processess inside the jail (default: your current uid). 
You can also use inside_ns_uid:outside_ns_uid:count convention here. Can be 
specified multiple times
+       Username/uid of processes inside the jail (default: your current uid). 
You can also use inside_ns_uid:outside_ns_uid:count convention here. Can be 
specified multiple times
  --group|-g VALUE
-       Groupname/gid of processess inside the jail (default: your current 
gid). You can also use inside_ns_gid:global_ns_gid:count convention here. Can 
be specified multiple times
+       Groupname/gid of processes inside the jail (default: your current gid). 
You can also use inside_ns_gid:global_ns_gid:count convention here. Can be 
specified multiple times
  --hostname|-H VALUE
        UTS name (hostname) of the jail (default: 'NSJAIL')
  --cwd|-D VALUE
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/caps.cc new/nsjail-3.0/caps.cc
--- old/nsjail-2.9/caps.cc      2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/caps.cc      2020-07-23 00:09:23.000000000 +0200
@@ -88,7 +88,7 @@
                        return cap.val;
                }
        }
-       LOG_W("Uknown capability: '%s'", name);
+       LOG_W("Unknown capability: '%s'", name);
        return -1;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/cmdline.cc new/nsjail-3.0/cmdline.cc
--- old/nsjail-2.9/cmdline.cc   2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/cmdline.cc   2020-07-23 00:09:23.000000000 +0200
@@ -77,8 +77,8 @@
     { { "execute_fd", no_argument, NULL, 0x0607 }, "Use execveat() to execute 
a file-descriptor instead of executing the binary path. In such case 
argv[0]/exec_file denotes a file path before mount namespacing" },
     { { "chroot", required_argument, NULL, 'c' }, "Directory containing / of 
the jail (default: none)" },
     { { "rw", no_argument, NULL, 0x601 }, "Mount chroot dir (/) R/W (default: 
R/O)" },
-    { { "user", required_argument, NULL, 'u' }, "Username/uid of processess 
inside the jail (default: your current uid). You can also use 
inside_ns_uid:outside_ns_uid:count convention here. Can be specified multiple 
times" },
-    { { "group", required_argument, NULL, 'g' }, "Groupname/gid of processess 
inside the jail (default: your current gid). You can also use 
inside_ns_gid:global_ns_gid:count convention here. Can be specified multiple 
times" },
+    { { "user", required_argument, NULL, 'u' }, "Username/uid of processes 
inside the jail (default: your current uid). You can also use 
inside_ns_uid:outside_ns_uid:count convention here. Can be specified multiple 
times" },
+    { { "group", required_argument, NULL, 'g' }, "Groupname/gid of processes 
inside the jail (default: your current gid). You can also use 
inside_ns_gid:global_ns_gid:count convention here. Can be specified multiple 
times" },
     { { "hostname", required_argument, NULL, 'H' }, "UTS name (hostname) of 
the jail (default: 'NSJAIL')" },
     { { "cwd", required_argument, NULL, 'D' }, "Directory in the namespace the 
process will run (default: '/')" },
     { { "port", required_argument, NULL, 'p' }, "TCP port to bind to (enables 
MODE_LISTEN_TCP) (default: 0)" },
@@ -507,10 +507,10 @@
                        nsjconf->max_conns_per_ip = strtoul(optarg, NULL, 0);
                        break;
                case 'l':
-                       logs::logFile(optarg);
+                       logs::logFile(optarg, STDERR_FILENO);
                        break;
                case 'L':
-                       logs::logFile(std::string("/dev/fd/") + optarg);
+                       logs::logFile("", std::strtol(optarg, NULL, 0));
                        break;
                case 'd':
                        nsjconf->daemonize = true;
@@ -862,7 +862,7 @@
        }
 
        if (nsjconf->daemonize && !logs::logSet()) {
-               logs::logFile(_LOG_DEFAULT_FILE);
+               logs::logFile(_LOG_DEFAULT_FILE, STDERR_FILENO);
        }
        if (!setupMounts(nsjconf.get())) {
                return nullptr;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/config.cc new/nsjail-3.0/config.cc
--- old/nsjail-2.9/config.cc    2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/config.cc    2020-07-23 00:09:23.000000000 +0200
@@ -79,13 +79,9 @@
                nsjconf->mode = MODE_STANDALONE_EXECVE;
                break;
        default:
-               LOG_E("Uknown running mode: %d", njc.mode());
+               LOG_E("Unknown running mode: %d", njc.mode());
                return false;
        }
-       if (njc.has_chroot_dir()) {
-               nsjconf->chroot = njc.chroot_dir();
-       }
-       nsjconf->is_root_rw = njc.is_root_rw();
        nsjconf->hostname = njc.hostname();
        nsjconf->cwd = njc.cwd();
        nsjconf->port = njc.port();
@@ -96,11 +92,12 @@
        nsjconf->daemonize = njc.daemon();
 
        if (njc.has_log_fd()) {
-               logs::logFile(std::string("/dev/fd/") + 
std::to_string(njc.log_fd()));
+               logs::logFile("", njc.log_fd());
        }
        if (njc.has_log_file()) {
-               logs::logFile(njc.log_file());
+               logs::logFile(njc.log_file(), STDERR_FILENO);
        }
+
        if (njc.has_log_level()) {
                switch (njc.log_level()) {
                case nsjail::LogLevel::DEBUG:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/config.proto new/nsjail-3.0/config.proto
--- old/nsjail-2.9/config.proto 2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/config.proto 2020-07-23 00:09:23.000000000 +0200
@@ -81,10 +81,6 @@
 
     /* Execution mode: see 'msg Mode' description for more */
     optional Mode mode = 3 [default = ONCE];
-    /* Equivalent to a bind mount with dst='/'. DEPRECATED: Use bind mounts. */
-    optional string chroot_dir = 4 [deprecated = true];
-    /* Applies both to the chroot_dir and to /proc mounts. DEPRECATED: Use 
bind mounts */
-    optional bool is_root_rw = 5 [default = false, deprecated = true];
     /* Hostname inside jail */
     optional string hostname = 8 [default = "NSJAIL"];
     /* Initial current working directory for the binary */
@@ -106,7 +102,7 @@
 
     /* FD to log to. */
     optional int32 log_fd = 16;
-    /* File to save lofs to */
+    /* File to save logs to. */
     optional string log_file = 17;
     /* Minimum log level displayed.
        See 'msg LogLevel' description for more */
@@ -157,7 +153,7 @@
     optional uint64 rlimit_nproc = 38 [default = 1024];
     optional RLimit rlimit_nproc_type = 39 [default = SOFT];
     /* In MiB, use the soft limit value by default */
-    optional uint64 rlimit_stack = 40 [default = 1048576];
+    optional uint64 rlimit_stack = 40 [default = 8];
     optional RLimit rlimit_stack_type = 41 [default = SOFT];
 
     /* Disable all rlimits, default to limits set by parent */
@@ -200,7 +196,7 @@
     optional bool seccomp_log = 60 [default = false];
 
     /* If > 0, maximum cumulative size of RAM used inside any jail */
-    optional uint64 cgroup_mem_max = 61 [default = 0]; /* In MiB */
+    optional uint64 cgroup_mem_max = 61 [default = 0]; /* In bytes */
     /* Mount point for cgroups-memory in your system */
     optional string cgroup_mem_mount = 62 [default = "/sys/fs/cgroup/memory"];
     /* Writeable directory (for the nsjail user) under cgroup_mem_mount */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/configs/tomcat8.cfg 
new/nsjail-3.0/configs/tomcat8.cfg
--- old/nsjail-2.9/configs/tomcat8.cfg  2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/configs/tomcat8.cfg  2020-07-23 00:09:23.000000000 +0200
@@ -72,7 +72,6 @@
        rw: false
 }
 
-
 mount {
        src: "/bin"
        dst: "/bin"
@@ -107,6 +106,7 @@
        is_bind: true
        rw: false
 }
+
 mount {
        src: "/usr/share/java"
        dst: "/usr/share/java"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/configs/xchat-with-net.cfg 
new/nsjail-3.0/configs/xchat-with-net.cfg
--- old/nsjail-2.9/configs/xchat-with-net.cfg   2019-09-02 16:10:28.000000000 
+0200
+++ new/nsjail-3.0/configs/xchat-with-net.cfg   2020-07-23 00:09:23.000000000 
+0200
@@ -7,11 +7,12 @@
 description: "The rest of available on the FS files/dires are libs and 
X-related files/dirs."
 description: ""
 description: "Run as:"
-description: "./nsjail --config configs/xchat-with-net.cfg --daemon -l 
/tmp/xchat.log"
+description: "./nsjail --config configs/xchat-with-net.cfg"
 
 mode: ONCE
 hostname: "XCHAT"
 cwd: "/user"
+daemon: true
 
 time_limit: 0
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/configs/znc-with-net.cfg 
new/nsjail-3.0/configs/znc-with-net.cfg
--- old/nsjail-2.9/configs/znc-with-net.cfg     1970-01-01 01:00:00.000000000 
+0100
+++ new/nsjail-3.0/configs/znc-with-net.cfg     2020-07-23 00:09:23.000000000 
+0200
@@ -0,0 +1,134 @@
+name: "znc-with-net"
+
+description: "This policy allows to run znc a jail. "
+description: "Networking is permitted with this setup (clone_newnet: false). "
+description: ""
+description: "The only permitted home directory is $HOME/.znc."
+description: ""
+description: "Run as: nsjail --config configs/znc-with-net.cfg"
+
+mode: ONCE
+hostname: "ZNC"
+cwd: "/home/znc"
+daemon: true
+
+time_limit: 0
+
+envar: "HOME=/home/znc"
+envar: "TMP=/tmp"
+
+log_fd: 2
+
+rlimit_as: 4096
+rlimit_cpu_type: INF
+rlimit_fsize: 4096
+rlimit_nofile: 128
+
+clone_newnet: false
+
+mount {
+       dst: "/proc"
+       fstype: "proc"
+}
+
+mount {
+       src: "/lib"
+       dst: "/lib"
+       is_bind: true
+}
+
+mount {
+       src: "/usr/lib"
+       dst: "/usr/lib"
+       is_bind: true
+}
+
+mount {
+       src: "/lib64"
+       dst: "/lib64"
+       is_bind: true
+       mandatory: false
+}
+
+mount {
+       src: "/lib32"
+       dst: "/lib32"
+       is_bind: true
+       mandatory: false
+}
+
+mount {
+       src: "/usr/share"
+       dst: "/usr/share"
+       is_bind: true
+}
+
+mount {
+       src: "/dev/urandom"
+       dst: "/dev/urandom"
+       is_bind: true
+       rw: true
+}
+
+mount {
+       src: "/dev/null"
+       dst: "/dev/null"
+       is_bind: true
+       rw: true
+}
+
+mount {
+       src: "/etc/resolv.conf"
+       dst: "/etc/resolv.conf"
+       is_bind: true
+       mandatory: false
+}
+
+mount {
+       src: "/etc/ssl"
+       dst: "/etc/ssl"
+       is_bind: true
+}
+
+mount {
+       dst: "/tmp"
+       fstype: "tmpfs"
+       rw: true
+       is_bind: false
+}
+
+mount {
+       dst: "/dev/shm"
+       fstype: "tmpfs"
+       rw: true
+       is_bind: false
+}
+
+mount {
+       dst: "/home/znc"
+       fstype: "tmpfs"
+       rw: true
+       is_bind: false
+}
+
+mount {
+       prefix_src_env: "HOME"
+       src: "/.znc"
+       dst: "/home/znc/.znc"
+       rw: true
+       is_bind: true
+       mandatory: true
+}
+
+seccomp_string: "KILL {"
+seccomp_string: "      ptrace,"
+seccomp_string: "      process_vm_readv,"
+seccomp_string: "      process_vm_writev"
+seccomp_string: "}"
+seccomp_string: "DEFAULT ALLOW"
+
+exec_bin {
+       path: "/usr/bin/znc"
+       arg: "-f"
+       exec_fd: true
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/logs.cc new/nsjail-3.0/logs.cc
--- old/nsjail-2.9/logs.cc      2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/logs.cc      2020-07-23 00:09:23.000000000 +0200
@@ -74,19 +74,21 @@
        _log_level = ll;
 }
 
-void logFile(const std::string& logfile) {
+void logFile(const std::string& log_file, int log_fd) {
        _log_set = true;
-       int newlogfd = TEMP_FAILURE_RETRY(
-           open(logfile.c_str(), O_CREAT | O_RDWR | O_APPEND | O_CLOEXEC, 
0640));
-       if (newlogfd == -1) {
-               PLOG_W("Couldn't open logfile open('%s')", logfile.c_str());
-               return;
+       int newlogfd = -1;
+       if (!log_file.empty()) {
+               newlogfd = TEMP_FAILURE_RETRY(
+                   open(log_file.c_str(), O_CREAT | O_RDWR | O_APPEND | 
O_CLOEXEC, 0640));
+               if (newlogfd == -1) {
+                       PLOG_W("Couldn't open('%s')", log_file.c_str());
+               }
        }
        /* Close previous log_fd */
        if (_log_fd > STDERR_FILENO) {
                close(_log_fd);
        }
-       setDupLogFdOr(newlogfd, STDERR_FILENO);
+       setDupLogFdOr(newlogfd, log_fd);
        close(newlogfd);
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/logs.h new/nsjail-3.0/logs.h
--- old/nsjail-2.9/logs.h       2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/logs.h       2020-07-23 00:09:23.000000000 +0200
@@ -59,7 +59,7 @@
     __attribute__((format(printf, 5, 6)));
 void logStop(int sig);
 void logLevel(enum llevel_t ll);
-void logFile(const std::string& logfile);
+void logFile(const std::string& log_file, int log_fd);
 bool logSet();
 
 }  // namespace logs
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/mnt.cc new/nsjail-3.0/mnt.cc
--- old/nsjail-2.9/mnt.cc       2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/mnt.cc       2020-07-23 00:09:23.000000000 +0200
@@ -178,8 +178,8 @@
                        return false;
                }
                if (!util::writeToFd(fd, mpt->src_content.data(), 
mpt->src_content.length())) {
-                       LOG_W("Writting %zu bytes to '%s' failed", 
mpt->src_content.length(),
-                           srcpath);
+                       LOG_W(
+                           "Writing %zu bytes to '%s' failed", 
mpt->src_content.length(), srcpath);
                        close(fd);
                        return false;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/net.cc new/nsjail-3.0/net.cc
--- old/nsjail-2.9/net.cc       2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/net.cc       2020-07-23 00:09:23.000000000 +0200
@@ -23,6 +23,7 @@
 
 #include <arpa/inet.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <net/if.h>
 #include <net/route.h>
 #include <netinet/in.h>
@@ -190,8 +191,8 @@
 
        unsigned cnt = 0;
        for (const auto& pid : nsjconf->pids) {
-               if (memcmp(addr.sin6_addr.s6_addr, 
pid.remote_addr.sin6_addr.s6_addr,
-                       sizeof(pid.remote_addr.sin6_addr.s6_addr)) == 0) {
+               if (memcmp(addr.sin6_addr.s6_addr, 
pid.second.remote_addr.sin6_addr.s6_addr,
+                       sizeof(pid.second.remote_addr.sin6_addr.s6_addr)) == 0) 
{
                        cnt++;
                }
        }
@@ -232,6 +233,10 @@
                PLOG_E("socket(AF_INET6)");
                return -1;
        }
+       if (fcntl(sockfd, F_SETFL, O_NONBLOCK)) {
+               PLOG_E("fcntl(%d, F_SETFL, O_NONBLOCK)", sockfd);
+               return -1;
+       }
        int so = 1;
        if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &so, sizeof(so)) == 
-1) {
                PLOG_E("setsockopt(%d, SO_REUSEADDR)", sockfd);
@@ -264,7 +269,7 @@
 int acceptConn(int listenfd) {
        struct sockaddr_in6 cli_addr;
        socklen_t socklen = sizeof(cli_addr);
-       int connfd = accept(listenfd, (struct sockaddr*)&cli_addr, &socklen);
+       int connfd = accept4(listenfd, (struct sockaddr*)&cli_addr, &socklen, 
SOCK_NONBLOCK);
        if (connfd == -1) {
                if (errno != EINTR) {
                        PLOG_E("accept(%d)", listenfd);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/nsjail.1 new/nsjail-3.0/nsjail.1
--- old/nsjail-2.9/nsjail.1     2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/nsjail.1     2020-07-23 00:09:23.000000000 +0200
@@ -44,10 +44,10 @@
 Mount chroot dir (/) R/W (default: R/O)
 .TP
 \fB\-\-user\fR|\fB\-u\fR VALUE
-Username/uid of processess inside the jail (default: your current uid). You 
can also use inside_ns_uid:outside_ns_uid:count convention here. Can be 
specified multiple times
+Username/uid of processes inside the jail (default: your current uid). You can 
also use inside_ns_uid:outside_ns_uid:count convention here. Can be specified 
multiple times
 .TP
 \fB\-\-group\fR|\fB\-g\fR VALUE
-Groupname/gid of processess inside the jail (default: your current gid). You 
can also use inside_ns_gid:global_ns_gid:count convention here. Can be 
specified multiple times
+Groupname/gid of processes inside the jail (default: your current gid). You 
can also use inside_ns_gid:global_ns_gid:count convention here. Can be 
specified multiple times
 .TP
 \fB\-\-hostname\fR|\fB\-H\fR VALUE
 UTS name (hostname) of the jail (default: 'NSJAIL')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/nsjail.cc new/nsjail-3.0/nsjail.cc
--- old/nsjail-2.9/nsjail.cc    2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/nsjail.cc    2020-07-23 00:09:23.000000000 +0200
@@ -21,6 +21,8 @@
 
 #include "nsjail.h"
 
+#include <fcntl.h>
+#include <poll.h>
 #include <signal.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -31,7 +33,10 @@
 #include <termios.h>
 #include <unistd.h>
 
+#include <algorithm>
+#include <cerrno>
 #include <memory>
+#include <vector>
 
 #include "cmdline.h"
 #include "logs.h"
@@ -47,10 +52,7 @@
 static __thread bool showProc = false;
 
 static void sigHandler(int sig) {
-       if (sig == SIGALRM) {
-               return;
-       }
-       if (sig == SIGCHLD) {
+       if (sig == SIGALRM || sig == SIGCHLD || sig == SIGPIPE) {
                return;
        }
        if (sig == SIGUSR1 || sig == SIGQUIT) {
@@ -74,7 +76,7 @@
 
        if (sig == SIGTTIN || sig == SIGTTOU) {
                sa.sa_handler = SIG_IGN;
-       };
+       }
        if (sigaction(sig, &sa, NULL) == -1) {
                PLOG_E("sigaction(%d)", sig);
                return false;
@@ -115,6 +117,99 @@
        return true;
 }
 
+static bool pipeTraffic(nsjconf_t* nsjconf, int listenfd) {
+       std::vector<struct pollfd> fds;
+       fds.reserve(nsjconf->pipes.size() * 3 + 1);
+       for (const auto& p : nsjconf->pipes) {
+               fds.push_back({
+                   .fd = p.sock_fd,
+                   .events = POLLIN | POLLOUT,
+                   .revents = 0,
+               });
+               fds.push_back({
+                   .fd = p.pipe_in,
+                   .events = POLLOUT,
+                   .revents = 0,
+               });
+               fds.push_back({
+                   .fd = p.pipe_out,
+                   .events = POLLIN,
+                   .revents = 0,
+               });
+       }
+       fds.push_back({
+           .fd = listenfd,
+           .events = POLLIN,
+           .revents = 0,
+       });
+       LOG_D("Waiting for fd activity");
+       while (poll(fds.data(), fds.size(), -1) > 0) {
+               if (sigFatal > 0 || showProc) {
+                       return false;
+               }
+               if (fds.back().revents != 0) {
+                       LOG_D("New connection ready");
+                       return true;
+               }
+               bool cleanup = false;
+               for (size_t i = 0; i < fds.size() - 1; ++i) {
+                       if (fds[i].revents & POLLIN) {
+                               fds[i].events &= ~POLLIN;
+                       }
+                       if (fds[i].revents & POLLOUT) {
+                               fds[i].events &= ~POLLOUT;
+                       }
+               }
+               for (size_t i = 0; i < fds.size() - 3; i += 3) {
+                       const size_t pipe_no = i / 3;
+                       int in, out;
+                       const char* direction;
+                       bool closed = false;
+                       std::tuple<int, int, const char*> direction_map[] = {
+                           {i, i + 1, "in"}, {i + 2, i, "out"}};
+                       for (const auto& entry : direction_map) {
+                               std::tie(in, out, direction) = entry;
+                               bool in_ready = (fds[in].events & POLLIN) == 0 
||
+                                               (fds[in].revents & POLLIN) == 
POLLIN;
+                               bool out_ready = (fds[out].events & POLLOUT) == 
0 ||
+                                                (fds[out].revents & POLLOUT) 
== POLLOUT;
+                               if (in_ready && out_ready) {
+                                       LOG_D("#%zu piping data %s", pipe_no, 
direction);
+                                       ssize_t rv = splice(fds[in].fd, 
nullptr, fds[out].fd,
+                                           nullptr, 4096, SPLICE_F_NONBLOCK);
+                                       if (rv == -1 && errno != EAGAIN) {
+                                               PLOG_E("splice fd pair #%zu 
{%d, %d}\n", pipe_no,
+                                                   fds[in].fd, fds[out].fd);
+                                       }
+                                       if (rv == 0) {
+                                               closed = true;
+                                       }
+                                       fds[in].events |= POLLIN;
+                                       fds[out].events |= POLLOUT;
+                               }
+                               if ((fds[in].revents & (POLLERR | POLLHUP)) != 
0 ||
+                                   (fds[out].revents & (POLLERR | POLLHUP)) != 
0) {
+                                       closed = true;
+                               }
+                       }
+                       if (closed) {
+                               LOG_D("#%zu connection closed", pipe_no);
+                               cleanup = true;
+                               close(nsjconf->pipes[pipe_no].sock_fd);
+                               close(nsjconf->pipes[pipe_no].pipe_in);
+                               close(nsjconf->pipes[pipe_no].pipe_out);
+                               nsjconf->pipes[pipe_no] = {};
+                       }
+               }
+               if (cleanup) {
+                       break;
+               }
+       }
+       nsjconf->pipes.erase(std::remove(nsjconf->pipes.begin(), 
nsjconf->pipes.end(), pipemap_t{}),
+           nsjconf->pipes.end());
+       return false;
+}
+
 static int listenMode(nsjconf_t* nsjconf) {
        int listenfd = net::getRecvSocket(nsjconf->bindhost.c_str(), 
nsjconf->port);
        if (listenfd == -1) {
@@ -131,10 +226,24 @@
                        showProc = false;
                        subproc::displayProc(nsjconf);
                }
-               int connfd = net::acceptConn(listenfd);
-               if (connfd >= 0) {
-                       subproc::runChild(nsjconf, connfd, connfd, connfd);
-                       close(connfd);
+               if (pipeTraffic(nsjconf, listenfd)) {
+                       int connfd = net::acceptConn(listenfd);
+                       if (connfd >= 0) {
+                               int in[2];
+                               int out[2];
+                               if (pipe(in) != 0 || pipe(out) != 0) {
+                                       PLOG_E("pipe");
+                                       continue;
+                               }
+                               nsjconf->pipes.push_back({
+                                   .sock_fd = connfd,
+                                   .pipe_in = in[1],
+                                   .pipe_out = out[0],
+                               });
+                               subproc::runChild(nsjconf, connfd, in[0], 
out[1], out[1]);
+                               close(in[0]);
+                               close(out[1]);
+                       }
                }
                subproc::reapProc(nsjconf);
        }
@@ -142,7 +251,8 @@
 
 static int standaloneMode(nsjconf_t* nsjconf) {
        for (;;) {
-               if (!subproc::runChild(nsjconf, STDIN_FILENO, STDOUT_FILENO, 
STDERR_FILENO)) {
+               if (!subproc::runChild(
+                       nsjconf, /* netfd= */ -1, STDIN_FILENO, STDOUT_FILENO, 
STDERR_FILENO)) {
                        LOG_E("Couldn't launch the child process");
                        return 0xff;
                }
@@ -203,7 +313,7 @@
        if (!nsjconf) {
                LOG_F("Couldn't parse cmdline options");
        }
-       if (nsjconf->daemonize && (daemon(0, 0) == -1)) {
+       if (nsjconf->daemonize && (daemon(/* nochdir= */ 1, /* noclose= */ 0) 
== -1)) {
                PLOG_F("daemon");
        }
        cmdline::logParams(nsjconf.get());
@@ -226,7 +336,9 @@
 
        sandbox::closePolicy(nsjconf.get());
        /* Try to restore the underlying console's params in case some program 
has changed it */
-       nsjail::setTC(STDIN_FILENO, trm.get());
+       if (!nsjconf->daemonize) {
+               nsjail::setTC(STDIN_FILENO, trm.get());
+       }
 
        LOG_D("Returning with %d", ret);
        return ret;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/nsjail.h new/nsjail-3.0/nsjail.h
--- old/nsjail-2.9/nsjail.h     2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/nsjail.h     2020-07-23 00:09:23.000000000 +0200
@@ -32,6 +32,7 @@
 #include <time.h>
 #include <unistd.h>
 
+#include <map>
 #include <string>
 #include <vector>
 
@@ -44,10 +45,10 @@
     SIGTERM,
     SIGTTIN,
     SIGTTOU,
+    SIGPIPE,
 };
 
 struct pids_t {
-       pid_t pid;
        time_t start;
        std::string remote_txt;
        struct sockaddr_in6 remote_addr;
@@ -81,6 +82,15 @@
        MODE_STANDALONE_RERUN
 };
 
+struct pipemap_t {
+       int sock_fd;
+       int pipe_in;
+       int pipe_out;
+       bool operator==(const pipemap_t& o) {
+               return sock_fd == o.sock_fd && pipe_in == o.pipe_in && pipe_out 
== o.pipe_out;
+       }
+};
+
 struct nsjconf_t {
        std::string exec_file;
        bool use_execveat;
@@ -150,13 +160,14 @@
        uid_t orig_uid;
        uid_t orig_euid;
        std::vector<mount_t> mountpts;
-       std::vector<pids_t> pids;
+       std::map<pid_t, pids_t> pids;
        std::vector<idmap_t> uids;
        std::vector<idmap_t> gids;
        std::vector<std::string> envs;
        std::vector<int> openfds;
        std::vector<int> caps;
        std::vector<std::string> ifaces;
+       std::vector<pipemap_t> pipes;
 };
 
 #endif /* _NSJAIL_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/subproc.cc new/nsjail-3.0/subproc.cc
--- old/nsjail-2.9/subproc.cc   2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/subproc.cc   2020-07-23 00:09:23.000000000 +0200
@@ -67,29 +67,33 @@
                const uintptr_t flag;
                const char* const name;
        } static const cloneFlags[] = {
-           NS_VALSTR_STRUCT(CLONE_VM),
-           NS_VALSTR_STRUCT(CLONE_FS),
-           NS_VALSTR_STRUCT(CLONE_FILES),
-           NS_VALSTR_STRUCT(CLONE_SIGHAND),
-           NS_VALSTR_STRUCT(CLONE_PTRACE),
-           NS_VALSTR_STRUCT(CLONE_VFORK),
-           NS_VALSTR_STRUCT(CLONE_PARENT),
-           NS_VALSTR_STRUCT(CLONE_THREAD),
-           NS_VALSTR_STRUCT(CLONE_NEWNS),
-           NS_VALSTR_STRUCT(CLONE_SYSVSEM),
-           NS_VALSTR_STRUCT(CLONE_SETTLS),
-           NS_VALSTR_STRUCT(CLONE_PARENT_SETTID),
-           NS_VALSTR_STRUCT(CLONE_CHILD_CLEARTID),
-           NS_VALSTR_STRUCT(CLONE_DETACHED),
-           NS_VALSTR_STRUCT(CLONE_UNTRACED),
-           NS_VALSTR_STRUCT(CLONE_CHILD_SETTID),
-           NS_VALSTR_STRUCT(CLONE_NEWCGROUP),
-           NS_VALSTR_STRUCT(CLONE_NEWUTS),
-           NS_VALSTR_STRUCT(CLONE_NEWIPC),
-           NS_VALSTR_STRUCT(CLONE_NEWUSER),
-           NS_VALSTR_STRUCT(CLONE_NEWPID),
-           NS_VALSTR_STRUCT(CLONE_NEWNET),
-           NS_VALSTR_STRUCT(CLONE_IO),
+               NS_VALSTR_STRUCT(CLONE_VM),
+               NS_VALSTR_STRUCT(CLONE_FS),
+               NS_VALSTR_STRUCT(CLONE_FILES),
+               NS_VALSTR_STRUCT(CLONE_SIGHAND),
+#if !defined(CLONE_PIDFD)
+#define CLONE_PIDFD 0x00001000
+#endif
+               NS_VALSTR_STRUCT(CLONE_PIDFD),
+               NS_VALSTR_STRUCT(CLONE_PTRACE),
+               NS_VALSTR_STRUCT(CLONE_VFORK),
+               NS_VALSTR_STRUCT(CLONE_PARENT),
+               NS_VALSTR_STRUCT(CLONE_THREAD),
+               NS_VALSTR_STRUCT(CLONE_NEWNS),
+               NS_VALSTR_STRUCT(CLONE_SYSVSEM),
+               NS_VALSTR_STRUCT(CLONE_SETTLS),
+               NS_VALSTR_STRUCT(CLONE_PARENT_SETTID),
+               NS_VALSTR_STRUCT(CLONE_CHILD_CLEARTID),
+               NS_VALSTR_STRUCT(CLONE_DETACHED),
+               NS_VALSTR_STRUCT(CLONE_UNTRACED),
+               NS_VALSTR_STRUCT(CLONE_CHILD_SETTID),
+               NS_VALSTR_STRUCT(CLONE_NEWCGROUP),
+               NS_VALSTR_STRUCT(CLONE_NEWUTS),
+               NS_VALSTR_STRUCT(CLONE_NEWIPC),
+               NS_VALSTR_STRUCT(CLONE_NEWUSER),
+               NS_VALSTR_STRUCT(CLONE_NEWPID),
+               NS_VALSTR_STRUCT(CLONE_NEWNET),
+               NS_VALSTR_STRUCT(CLONE_IO),
        };
 
        uintptr_t knownFlagMask = CSIGNAL;
@@ -129,7 +133,8 @@
 static const char kSubprocDoneChar = 'D';
 static const char kSubprocErrorChar = 'E';
 
-static void subprocNewProc(nsjconf_t* nsjconf, int fd_in, int fd_out, int 
fd_err, int pipefd) {
+static void subprocNewProc(
+    nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err, int 
pipefd) {
        if (!contain::setupFD(nsjconf, fd_in, fd_out, fd_err)) {
                return;
        }
@@ -170,7 +175,7 @@
                putenv(const_cast<char*>(env.c_str()));
        }
 
-       auto connstr = net::connToText(fd_in, /* remote= */ true, NULL);
+       auto connstr = net::connToText(netfd, /* remote= */ true, NULL);
        LOG_I("Executing '%s' for '%s'", nsjconf->exec_file.c_str(), 
connstr.c_str());
 
        std::vector<const char*> argv;
@@ -203,7 +208,6 @@
 static void addProc(nsjconf_t* nsjconf, pid_t pid, int sock) {
        pids_t p;
 
-       p.pid = pid;
        p.start = time(NULL);
        p.remote_txt = net::connToText(sock, /* remote= */ true, 
&p.remote_addr);
 
@@ -211,24 +215,27 @@
        snprintf(fname, sizeof(fname), "/proc/%d/syscall", (int)pid);
        p.pid_syscall_fd = TEMP_FAILURE_RETRY(open(fname, O_RDONLY | 
O_CLOEXEC));
 
-       nsjconf->pids.push_back(p);
+       if (nsjconf->pids.find(pid) != nsjconf->pids.end()) {
+               LOG_F("pid=%d already exists", pid);
+       }
+       nsjconf->pids.insert(std::make_pair(pid, p));
 
-       LOG_D("Added pid=%d with start time '%u' to the queue for IP: '%s'", 
p.pid,
+       LOG_D("Added pid=%d with start time '%u' to the queue for IP: '%s'", 
pid,
            (unsigned int)p.start, p.remote_txt.c_str());
 }
 
 static void removeProc(nsjconf_t* nsjconf, pid_t pid) {
-       for (auto p = nsjconf->pids.begin(); p != nsjconf->pids.end(); ++p) {
-               if (p->pid == pid) {
-                       LOG_D("Removing pid=%d from the queue (IP:'%s', start 
time:'%s')", p->pid,
-                           p->remote_txt.c_str(), 
util::timeToStr(p->start).c_str());
-                       close(p->pid_syscall_fd);
-                       nsjconf->pids.erase(p);
-
-                       return;
-               }
+       if (nsjconf->pids.find(pid) == nsjconf->pids.end()) {
+               LOG_W("pid=%d doesn't exist ?", pid);
+               return;
        }
-       LOG_W("pid=%d not found (?)", pid);
+
+       const auto& p = nsjconf->pids[pid];
+       LOG_D("Removed pid=%d from the queue (IP:'%s', start time:'%s')", pid, 
p.remote_txt.c_str(),
+           util::timeToStr(p.start).c_str());
+
+       close(p.pid_syscall_fd);
+       nsjconf->pids.erase(pid);
 }
 
 int countProc(nsjconf_t* nsjconf) {
@@ -239,27 +246,19 @@
        LOG_I("Total number of spawned namespaces: %d", countProc(nsjconf));
        time_t now = time(NULL);
        for (const auto& pid : nsjconf->pids) {
-               time_t diff = now - pid.start;
+               time_t diff = now - pid.second.start;
                uint64_t left = nsjconf->tlimit ? nsjconf->tlimit - 
(uint64_t)diff : 0;
-               LOG_I("pid=%d, Remote host: %s, Run time: %ld sec. (time left: 
%" PRId64 " sec.)",
-                   pid.pid, pid.remote_txt.c_str(), (long)diff, left);
-       }
-}
-
-static const pids_t* getPidElem(nsjconf_t* nsjconf, pid_t pid) {
-       for (const auto& p : nsjconf->pids) {
-               if (p.pid == pid) {
-                       return &p;
-               }
+               LOG_I("pid=%d, Remote host: %s, Run time: %ld sec. (time left: 
%s s.)", pid.first,
+                   pid.second.remote_txt.c_str(), (long)diff,
+                   nsjconf->tlimit ? std::to_string(left).c_str() : 
"unlimited");
        }
-       return NULL;
 }
 
 static void seccompViolation(nsjconf_t* nsjconf, siginfo_t* si) {
-       LOG_W("pid=%d commited a syscall/seccomp violation and exited with 
SIGSYS", si->si_pid);
+       LOG_W("pid=%d committed a syscall/seccomp violation and exited with 
SIGSYS", si->si_pid);
 
-       const pids_t* p = getPidElem(nsjconf, si->si_pid);
-       if (p == NULL) {
+       const auto& p = nsjconf->pids.find(si->si_pid);
+       if (p == nsjconf->pids.end()) {
                LOG_W("pid=%d SiSyscall: %d, SiCode: %d, SiErrno: %d, SiSigno: 
%d", (int)si->si_pid,
                    si->si_syscall, si->si_code, si->si_errno, si->si_signo);
                LOG_E("Couldn't find pid element in the subproc list for 
pid=%d", (int)si->si_pid);
@@ -267,7 +266,7 @@
        }
 
        char buf[4096];
-       ssize_t rdsize = util::readFromFd(p->pid_syscall_fd, buf, sizeof(buf) - 
1);
+       ssize_t rdsize = util::readFromFd(p->second.pid_syscall_fd, buf, 
sizeof(buf) - 1);
        if (rdsize < 1) {
                LOG_W("pid=%d, SiSyscall: %d, SiCode: %d, SiErrno: %d, SiSigno: 
%d",
                    (int)si->si_pid, si->si_syscall, si->si_code, si->si_errno, 
si->si_signo);
@@ -308,9 +307,9 @@
                }
 
                std::string remote_txt = "[UNKNOWN]";
-               const pids_t* elem = getPidElem(nsjconf, pid);
-               if (elem) {
-                       remote_txt = elem->remote_txt;
+               const auto& p = nsjconf->pids.find(pid);
+               if (p != nsjconf->pids.end()) {
+                       remote_txt = p->second.remote_txt;
                }
 
                if (WIFEXITED(status)) {
@@ -353,11 +352,11 @@
                if (nsjconf->tlimit == 0) {
                        continue;
                }
-               pid_t pid = p.pid;
-               time_t diff = now - p.start;
+               pid_t pid = p.first;
+               time_t diff = now - p.second.start;
                if ((uint64_t)diff >= nsjconf->tlimit) {
                        LOG_I("pid=%d run time >= time limit (%ld >= %" PRIu64 
") (%s). Killing it",
-                           pid, (long)diff, nsjconf->tlimit, 
p.remote_txt.c_str());
+                           pid, (long)diff, nsjconf->tlimit, 
p.second.remote_txt.c_str());
                        /*
                         * Probably a kernel bug - some processes cannot be 
killed with KILL if
                         * they're namespaced, and in a stopped state
@@ -373,7 +372,7 @@
 
 void killAndReapAll(nsjconf_t* nsjconf) {
        while (!nsjconf->pids.empty()) {
-               pid_t pid = nsjconf->pids.front().pid;
+               pid_t pid = nsjconf->pids.begin()->first;
                if (kill(pid, SIGKILL) == 0) {
                        reapProc(nsjconf, pid, true);
                } else {
@@ -409,8 +408,8 @@
        return true;
 }
 
-bool runChild(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err) {
-       if (!net::limitConns(nsjconf, fd_in)) {
+bool runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int 
fd_err) {
+       if (!net::limitConns(nsjconf, netfd)) {
                return true;
        }
        unsigned long flags = 0UL;
@@ -426,7 +425,7 @@
                if (unshare(flags) == -1) {
                        PLOG_F("unshare(%s)", cloneFlagsToStr(flags).c_str());
                }
-               subprocNewProc(nsjconf, fd_in, fd_out, fd_err, -1);
+               subprocNewProc(nsjconf, netfd, fd_in, fd_out, fd_err, -1);
                LOG_F("Launching new process failed");
        }
 
@@ -444,7 +443,7 @@
        pid_t pid = cloneProc(flags);
        if (pid == 0) {
                close(parent_fd);
-               subprocNewProc(nsjconf, fd_in, fd_out, fd_err, child_fd);
+               subprocNewProc(nsjconf, netfd, fd_in, fd_out, fd_err, child_fd);
                util::writeToFd(child_fd, &kSubprocErrorChar, 
sizeof(kSubprocErrorChar));
                LOG_F("Launching child process failed");
        }
@@ -466,7 +465,7 @@
                close(parent_fd);
                return false;
        }
-       addProc(nsjconf, pid, fd_in);
+       addProc(nsjconf, pid, netfd);
 
        if (!initParent(nsjconf, pid, parent_fd)) {
                close(parent_fd);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/subproc.h new/nsjail-3.0/subproc.h
--- old/nsjail-2.9/subproc.h    2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/subproc.h    2020-07-23 00:09:23.000000000 +0200
@@ -33,7 +33,7 @@
 
 namespace subproc {
 
-bool runChild(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err);
+bool 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);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nsjail-2.9/user.cc new/nsjail-3.0/user.cc
--- old/nsjail-2.9/user.cc      2019-09-02 16:10:28.000000000 +0200
+++ new/nsjail-3.0/user.cc      2020-07-23 00:09:23.000000000 +0200
@@ -43,6 +43,22 @@
 #include "subproc.h"
 #include "util.h"
 
+#define STR_(x) #x
+#define STR(x) STR_(x)
+
+constexpr char kNewUidPath[] =
+#ifdef NEWUIDMAP_PATH
+    STR(NEWUIDMAP_PATH);
+#else
+    "/usr/bin/newuidmap";
+#endif
+constexpr char kNewGidPath[] =
+#ifdef NEWGIDMAP_PATH
+    STR(NEWGIDMAP_PATH);
+#else
+    "/usr/bin/newgidmap";
+#endif
+
 namespace user {
 
 static bool setResGid(gid_t gid) {
@@ -77,12 +93,21 @@
        return true;
 }
 
+static bool hasGidMapSelf(nsjconf_t* nsjconf) {
+       for (const auto& gid : nsjconf->gids) {
+               if (!gid.is_newidmap) {
+                       return true;
+               }
+       }
+       return false;
+}
+
 static bool setGroupsDeny(nsjconf_t* nsjconf, pid_t pid) {
        /*
         * No need to write 'deny' to /proc/pid/setgroups if our euid==0, as 
writing to
         * uid_map/gid_map will succeed anyway
         */
-       if (!nsjconf->clone_newuser || nsjconf->orig_euid == 0) {
+       if (!nsjconf->clone_newuser || nsjconf->orig_euid == 0 || 
!hasGidMapSelf(nsjconf)) {
                return true;
        }
 
@@ -152,11 +177,11 @@
        return true;
 }
 
-/* Use /usr/bin/newgidmap for writing the gid map */
-static bool gidMapExternal(nsjconf_t* nsjconf, pid_t pid UNUSED) {
+/* Use newgidmap for writing the gid map */
+static bool gidMapExternal(nsjconf_t* nsjconf, pid_t pid) {
        bool use = false;
 
-       std::vector<std::string> argv = {"/usr/bin/newgidmap", 
std::to_string(pid)};
+       std::vector<std::string> argv = {kNewGidPath, std::to_string(pid)};
        for (const auto& gid : nsjconf->gids) {
                if (!gid.is_newidmap) {
                        continue;
@@ -171,18 +196,18 @@
                return true;
        }
        if (subproc::systemExe(argv, environ) != 0) {
-               LOG_E("'/usr/bin/newgidmap' failed");
+               LOG_E("'%s' failed", kNewGidPath);
                return false;
        }
 
        return true;
 }
 
-/* Use /usr/bin/newuidmap for writing the uid map */
-static bool uidMapExternal(nsjconf_t* nsjconf, pid_t pid UNUSED) {
+/* Use newuidmap for writing the uid map */
+static bool uidMapExternal(nsjconf_t* nsjconf, pid_t pid) {
        bool use = false;
 
-       std::vector<std::string> argv = {"/usr/bin/newuidmap", 
std::to_string(pid)};
+       std::vector<std::string> argv = {kNewUidPath, std::to_string(pid)};
        for (const auto& uid : nsjconf->uids) {
                if (!uid.is_newidmap) {
                        continue;
@@ -197,7 +222,7 @@
                return true;
        }
        if (subproc::systemExe(argv, environ) != 0) {
-               LOG_E("'/usr/bin/newuidmap' failed");
+               LOG_E("'%s' failed", kNewUidPath);
                return false;
        }
 
@@ -257,22 +282,22 @@
        groupsString += "]";
 
        if (!setResGid(nsjconf->gids[0].inside_id)) {
-               PLOG_E("setresgid(%u)", nsjconf->gids[0].inside_id);
+               PLOG_E("setresgid(%lu)", (unsigned 
long)nsjconf->gids[0].inside_id);
                return false;
        }
 
-       LOG_D("setgroups(%lu, %s)", groups.size(), groupsString.c_str());
+       LOG_D("setgroups(%zu, %s)", groups.size(), groupsString.c_str());
        if (setgroups(groups.size(), groups.data()) == -1) {
                /* Indicate error if specific groups were requested */
                if (groups.size() > 0) {
-                       PLOG_E("setgroups(%lu, %s) failed", groups.size(), 
groupsString.c_str());
+                       PLOG_E("setgroups(%zu, %s) failed", groups.size(), 
groupsString.c_str());
                        return false;
                }
-               PLOG_D("setgroups(%lu, %s) failed", groups.size(), 
groupsString.c_str());
+               PLOG_D("setgroups(%zu, %s) failed", groups.size(), 
groupsString.c_str());
        }
 
        if (!setResUid(nsjconf->uids[0].inside_id)) {
-               PLOG_E("setresuid(%u)", nsjconf->uids[0].inside_id);
+               PLOG_E("setresuid(%lu)", (unsigned 
long)nsjconf->uids[0].inside_id);
                return false;
        }
 


Reply via email to