config: Implement --stderr_to_null
authorRobert Swiecki <robert@swiecki.net>
Mon, 25 Jun 2018 01:12:27 +0000 (03:12 +0200)
committerRobert Swiecki <robert@swiecki.net>
Mon, 25 Jun 2018 01:12:27 +0000 (03:12 +0200)
cmdline.cc
config.cc
config.proto
contain.cc
nsjail.h

index c7e15d0..6736f40 100644 (file)
@@ -99,6 +99,7 @@ struct custom_option custom_opts[] = {
     { { "silent", no_argument, NULL, 0x0502 }, "Redirect child process' fd:0/1/2 to /dev/null" },
     { { "skip_setsid", no_argument, NULL, 0x0504 }, "Don't call setsid(), allows for terminal signal handling in the sandboxed process. Dangerous" },
     { { "pass_fd", required_argument, NULL, 0x0505 }, "Don't close this FD before executing the child process (can be specified multiple times), by default: 0/1/2 are kept open" },
+    { { "stderr_to_null", no_argument, NULL, 0x0506 }, "Redirect FD=2 (STDERR_FILENO) to /dev/null" },
     { { "disable_no_new_privs", no_argument, NULL, 0x0507 }, "Don't set the prctl(NO_NEW_PRIVS, 1) (DANGEROUS)" },
     { { "rlimit_as", required_argument, NULL, 0x0201 }, "RLIMIT_AS in MB, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 512)" },
     { { "rlimit_core", required_argument, NULL, 0x0202 }, "RLIMIT_CORE in MB, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 0)" },
@@ -396,6 +397,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
        nsjconf->is_root_rw = false;
        nsjconf->is_silent = false;
        nsjconf->skip_setsid = false;
+       nsjconf->stderr_to_null = false;
        nsjconf->max_conns_per_ip = 0;
        nsjconf->proc_path = "/proc";
        nsjconf->is_proc_rw = false;
@@ -570,6 +572,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                case 0x0505:
                        nsjconf->openfds.push_back((int)strtol(optarg, NULL, 0));
                        break;
+               case 0x0506:
+                       nsjconf->stderr_to_null = true;
+                       break;
                case 0x0507:
                        nsjconf->disable_no_new_privs = true;
                        break;
index fd82196..91377d0 100644 (file)
--- a/config.cc
+++ b/config.cc
@@ -144,6 +144,7 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
                nsjconf->openfds.push_back(i);
        }
 
+       nsjconf->stderr_to_null = njc.stderr_to_null();
        nsjconf->disable_no_new_privs = njc.disable_no_new_privs();
 
        nsjconf->rl_as =
index a57df68..9a25332 100644 (file)
@@ -124,6 +124,8 @@ message NsJailConfig {
        job control / signals. Dangerous, can be used to put
        characters into the controlling terminal back */
     optional bool skip_setsid = 24 [default = false];
+    /* Redirect sdterr of the process to /dev/null instead of the socket or original TTY */
+    optional bool stderr_to_null = 79 [default = false];
     /* Which FDs should be passed to the newly executed process
        By default only FD=0,1,2 are passed */
     repeated int32 pass_fd = 25;
index bfc1d1f..18c43d4 100644 (file)
@@ -263,25 +263,30 @@ static bool containMakeFdsCOE(nsjconf_t* nsjconf) {
 }
 
 bool setupFD(nsjconf_t* nsjconf, int fd_in, int fd_out, int fd_err) {
-       if (nsjconf->mode != MODE_LISTEN_TCP) {
-               if (!nsjconf->is_silent) {
-                       return true;
+       if (nsjconf->stderr_to_null) {
+               LOG_D("Redirecting FD=2 (STDERR_FILENO) to /dev/null");
+               if ((fd_err = TEMP_FAILURE_RETRY(open("/dev/null", O_RDWR))) == -1) {
+                       PLOG_E("open('/dev/null', O_RDWR");
+                       return false;
                }
+       }
+       if (nsjconf->is_silent) {
+               LOG_D("Redirecting FD=0/1/2 (STDIN/OUT/ERR_FILENO) to /dev/null");
                if (TEMP_FAILURE_RETRY(fd_in = fd_out = fd_err = open("/dev/null", O_RDWR)) == -1) {
                        PLOG_E("open('/dev/null', O_RDWR)");
                        return false;
                }
        }
        /* Set stdin/stdout/stderr to the net */
-       if (TEMP_FAILURE_RETRY(dup2(fd_in, STDIN_FILENO)) == -1) {
+       if (fd_in != STDIN_FILENO && TEMP_FAILURE_RETRY(dup2(fd_in, STDIN_FILENO)) == -1) {
                PLOG_E("dup2(%d, STDIN_FILENO)", fd_in);
                return false;
        }
-       if (TEMP_FAILURE_RETRY(dup2(fd_out, STDOUT_FILENO)) == -1) {
+       if (fd_out != STDOUT_FILENO && TEMP_FAILURE_RETRY(dup2(fd_out, STDOUT_FILENO)) == -1) {
                PLOG_E("dup2(%d, STDOUT_FILENO)", fd_out);
                return false;
        }
-       if (TEMP_FAILURE_RETRY(dup2(fd_err, STDERR_FILENO)) == -1) {
+       if (fd_err != STDERR_FILENO && TEMP_FAILURE_RETRY(dup2(fd_err, STDERR_FILENO)) == -1) {
                PLOG_E("dup2(%d, STDERR_FILENO)", fd_err);
                return false;
        }
index 69657a8..3838230 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -116,6 +116,7 @@ struct nsjconf_t {
        bool is_root_rw;
        bool is_silent;
        bool skip_setsid;
+       bool stderr_to_null;
        unsigned int max_conns_per_ip;
        std::string proc_path;
        bool is_proc_rw;