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')
|
Mode of the 'vs' interface. Can be either 'private', 'vepa', 'bridge' or 'passthru' (default: 'private')
|
||||||
--disable_tsc
|
--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.
|
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:
|
Examples:
|
||||||
Wait on a port 31337 for connections, and run /bin/sh
|
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_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')" },
|
{ { "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." },
|
{ { "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
|
// clang-format on
|
||||||
|
|
||||||
@ -480,6 +481,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
nsjconf->iface_vs_ma = "";
|
nsjconf->iface_vs_ma = "";
|
||||||
nsjconf->iface_vs_mo = "private";
|
nsjconf->iface_vs_mo = "private";
|
||||||
nsjconf->disable_tsc = false;
|
nsjconf->disable_tsc = false;
|
||||||
|
nsjconf->forward_signals = false;
|
||||||
nsjconf->orig_uid = getuid();
|
nsjconf->orig_uid = getuid();
|
||||||
nsjconf->orig_euid = geteuid();
|
nsjconf->orig_euid = geteuid();
|
||||||
nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||||
@ -861,6 +863,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
|
|||||||
case 0x707:
|
case 0x707:
|
||||||
nsjconf->disable_tsc = true;
|
nsjconf->disable_tsc = true;
|
||||||
break;
|
break;
|
||||||
|
case 0x708:
|
||||||
|
nsjconf->forward_signals = true;
|
||||||
|
break;
|
||||||
case 0x801:
|
case 0x801:
|
||||||
nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
|
nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
|
@ -282,6 +282,8 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
|
|||||||
|
|
||||||
nsjconf->disable_tsc = njc.disable_tsc();
|
nsjconf->disable_tsc = njc.disable_tsc();
|
||||||
|
|
||||||
|
nsjconf->forward_signals = njc.forward_signals();
|
||||||
|
|
||||||
if (njc.has_exec_bin()) {
|
if (njc.has_exec_bin()) {
|
||||||
if (njc.exec_bin().has_path()) {
|
if (njc.exec_bin().has_path()) {
|
||||||
nsjconf->exec_file = njc.exec_bin().path();
|
nsjconf->exec_file = njc.exec_bin().path();
|
||||||
|
@ -268,4 +268,8 @@ message NsJailConfig {
|
|||||||
optional Exe exec_bin = 90;
|
optional Exe exec_bin = 90;
|
||||||
|
|
||||||
optional bool disable_tsc = 93 [default = false];
|
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 (;;) {
|
for (;;) {
|
||||||
if (sigFatal > 0) {
|
if (sigFatal > 0) {
|
||||||
subproc::killAndReapAll(nsjconf);
|
subproc::killAndReapAll(nsjconf, nsjconf->forward_signals ? sigFatal : SIGKILL);
|
||||||
logs::logStop(sigFatal);
|
logs::logStop(sigFatal);
|
||||||
close(listenfd);
|
close(listenfd);
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
@ -285,7 +285,7 @@ static int standaloneMode(nsjconf_t* nsjconf) {
|
|||||||
subproc::displayProc(nsjconf);
|
subproc::displayProc(nsjconf);
|
||||||
}
|
}
|
||||||
if (sigFatal > 0) {
|
if (sigFatal > 0) {
|
||||||
subproc::killAndReapAll(nsjconf);
|
subproc::killAndReapAll(nsjconf, nsjconf->forward_signals ? sigFatal : SIGKILL);
|
||||||
logs::logStop(sigFatal);
|
logs::logStop(sigFatal);
|
||||||
return (128 + 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_ma;
|
||||||
std::string iface_vs_mo;
|
std::string iface_vs_mo;
|
||||||
bool disable_tsc;
|
bool disable_tsc;
|
||||||
|
bool forward_signals;
|
||||||
std::string cgroup_mem_mount;
|
std::string cgroup_mem_mount;
|
||||||
std::string cgroup_mem_parent;
|
std::string cgroup_mem_parent;
|
||||||
size_t cgroup_mem_max;
|
size_t cgroup_mem_max;
|
||||||
|
@ -389,10 +389,10 @@ int reapProc(nsjconf_t* nsjconf) {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
void killAndReapAll(nsjconf_t* nsjconf) {
|
void killAndReapAll(nsjconf_t* nsjconf, int signal) {
|
||||||
while (!nsjconf->pids.empty()) {
|
while (!nsjconf->pids.empty()) {
|
||||||
pid_t pid = nsjconf->pids.begin()->first;
|
pid_t pid = nsjconf->pids.begin()->first;
|
||||||
if (kill(pid, SIGKILL) == 0) {
|
if (kill(pid, signal) == 0) {
|
||||||
reapProc(nsjconf, pid, true);
|
reapProc(nsjconf, pid, true);
|
||||||
} else {
|
} else {
|
||||||
removeProc(nsjconf, pid);
|
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);
|
pid_t runChild(nsjconf_t* nsjconf, int listen_fd, int fd_in, int fd_out, int fd_err);
|
||||||
int countProc(nsjconf_t* nsjconf);
|
int countProc(nsjconf_t* nsjconf);
|
||||||
void displayProc(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 */
|
/* Returns the exit code of the first failing subprocess, or 0 if none fail */
|
||||||
int reapProc(nsjconf_t* nsjconf);
|
int reapProc(nsjconf_t* nsjconf);
|
||||||
int systemExe(const std::vector<std::string>& args, char** env);
|
int systemExe(const std::vector<std::string>& args, char** env);
|
||||||
|
Loading…
Reference in New Issue
Block a user