Merge pull request #197 from pks-t/pks-forward-signals

Optionally forward fatal signals
This commit is contained in:
robertswiecki 2022-06-11 12:08:21 +02:00 committed by GitHub
commit d88be25986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 19 additions and 5 deletions

View File

@ -534,6 +534,8 @@ Options:
Mode of the 'vs' interface. Can be either 'private', 'vepa', 'bridge' or 'passthru' (default: 'private')
--disable_tsc
Disable rdtsc and rdtscp instructions. WARNING: To make it effective, you also need to forbid `prctl(PR_SET_TSC, PR_TSC_ENABLE, ...)` in seccomp rules! (x86 and x86_64 only). Dynamic binaries produced by GCC seem to rely on RDTSC, but static ones should work.
--forward_signals
Forward fatal signals to the child process instead of always using SIKGILL.
Examples:
Wait on a port 31337 for connections, and run /bin/sh

View File

@ -167,6 +167,7 @@ struct custom_option custom_opts[] = {
{ { "macvlan_vs_ma", required_argument, NULL, 0x705 }, "MAC-address of the 'vs' interface (e.g. \"ba:ad:ba:be:45:00\")" },
{ { "macvlan_vs_mo", required_argument, NULL, 0x706 }, "Mode of the 'vs' interface. Can be either 'private', 'vepa', 'bridge' or 'passthru' (default: 'private')" },
{ { "disable_tsc", no_argument, NULL, 0x707 }, "Disable rdtsc and rdtscp instructions. WARNING: To make it effective, you also need to forbid `prctl(PR_SET_TSC, PR_TSC_ENABLE, ...)` in seccomp rules! (x86 and x86_64 only). Dynamic binaries produced by GCC seem to rely on RDTSC, but static ones should work." },
{ { "forward_signals", no_argument, NULL, 0x708 }, "Forward fatal signals to the child process instead of always using SIKGILL." },
};
// clang-format on
@ -480,6 +481,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
nsjconf->iface_vs_ma = "";
nsjconf->iface_vs_mo = "private";
nsjconf->disable_tsc = false;
nsjconf->forward_signals = false;
nsjconf->orig_uid = getuid();
nsjconf->orig_euid = geteuid();
nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
@ -861,6 +863,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
case 0x707:
nsjconf->disable_tsc = true;
break;
case 0x708:
nsjconf->forward_signals = true;
break;
case 0x801:
nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
break;

View File

@ -282,6 +282,8 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
nsjconf->disable_tsc = njc.disable_tsc();
nsjconf->forward_signals = njc.forward_signals();
if (njc.has_exec_bin()) {
if (njc.exec_bin().has_path()) {
nsjconf->exec_file = njc.exec_bin().path();

View File

@ -268,4 +268,8 @@ message NsJailConfig {
optional Exe exec_bin = 90;
optional bool disable_tsc = 93 [default = false];
/* Set this to true to forward fatal signals to the child process instead
* of always using SIGKILL. */
optional bool forward_signals = 94 [default = false];
}

View File

@ -222,7 +222,7 @@ static int listenMode(nsjconf_t* nsjconf) {
}
for (;;) {
if (sigFatal > 0) {
subproc::killAndReapAll(nsjconf);
subproc::killAndReapAll(nsjconf, nsjconf->forward_signals ? sigFatal : SIGKILL);
logs::logStop(sigFatal);
close(listenfd);
return EXIT_SUCCESS;
@ -285,7 +285,7 @@ static int standaloneMode(nsjconf_t* nsjconf) {
subproc::displayProc(nsjconf);
}
if (sigFatal > 0) {
subproc::killAndReapAll(nsjconf);
subproc::killAndReapAll(nsjconf, nsjconf->forward_signals ? sigFatal : SIGKILL);
logs::logStop(sigFatal);
return (128 + sigFatal);
}

View File

@ -146,6 +146,7 @@ struct nsjconf_t {
std::string iface_vs_ma;
std::string iface_vs_mo;
bool disable_tsc;
bool forward_signals;
std::string cgroup_mem_mount;
std::string cgroup_mem_parent;
size_t cgroup_mem_max;

View File

@ -389,10 +389,10 @@ int reapProc(nsjconf_t* nsjconf) {
return rv;
}
void killAndReapAll(nsjconf_t* nsjconf) {
void killAndReapAll(nsjconf_t* nsjconf, int signal) {
while (!nsjconf->pids.empty()) {
pid_t pid = nsjconf->pids.begin()->first;
if (kill(pid, SIGKILL) == 0) {
if (kill(pid, signal) == 0) {
reapProc(nsjconf, pid, true);
} else {
removeProc(nsjconf, pid);

View File

@ -37,7 +37,7 @@ namespace subproc {
pid_t 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);
void killAndReapAll(nsjconf_t* nsjconf, int signal);
/* Returns the exit code of the first failing subprocess, or 0 if none fail */
int reapProc(nsjconf_t* nsjconf);
int systemExe(const std::vector<std::string>& args, char** env);