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; }