From 272a85477a3a150a1f4a7a588a33d90b2d3c6ebc Mon Sep 17 00:00:00 2001 From: Robert Swiecki Date: Mon, 25 Jun 2018 03:12:27 +0200 Subject: [PATCH] config: Implement --stderr_to_null --- cmdline.cc | 5 +++++ config.cc | 1 + config.proto | 2 ++ contain.cc | 17 +++++++++++------ nsjail.h | 1 + 5 files changed, 20 insertions(+), 6 deletions(-) diff --git a/cmdline.cc b/cmdline.cc index c7e15d0..6736f40 100644 --- a/cmdline.cc +++ b/cmdline.cc @@ -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 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 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; diff --git a/config.cc b/config.cc index fd82196..91377d0 100644 --- 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 = diff --git a/config.proto b/config.proto index a57df68..9a25332 100644 --- a/config.proto +++ b/config.proto @@ -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; diff --git a/contain.cc b/contain.cc index bfc1d1f..18c43d4 100644 --- a/contain.cc +++ b/contain.cc @@ -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; } diff --git a/nsjail.h b/nsjail.h index 69657a8..3838230 100644 --- 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;