Merge pull request #197 from pks-t/pks-forward-signals
Optionally forward fatal signals
This commit is contained in:
commit
d88be25986
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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];
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
1
nsjail.h
1
nsjail.h
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user