{ { "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)" },
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;
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;
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 =
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;
}
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;
}
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;