aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Kowalczyk <redford@dragonsector.pl>2022-02-17 23:53:13 +0100
committerMichał Kowalczyk <redford@dragonsector.pl>2022-02-17 23:53:13 +0100
commit16b4416d758f7fc413c3e0fc0c67cd41bb0eaaee (patch)
treefb332566b4a6ada65ad9a35826362d5b9d750cb8
parent999d4631f33d27a9a1ecde6edbd0a1381a09f87b (diff)
downloadnsjail-16b4416d758f7fc413c3e0fc0c67cd41bb0eaaee.tar.gz
Add `disable_tsc` option
Implemented via prctl(PR_SET_TSC, PR_TSC_SIGSEGV, ...).
-rw-r--r--cmdline.cc5
-rw-r--r--config.cc2
-rw-r--r--config.proto2
-rw-r--r--contain.cc11
-rw-r--r--nsjail.h1
5 files changed, 21 insertions, 0 deletions
diff --git a/cmdline.cc b/cmdline.cc
index 1b52b33..e348caf 100644
--- a/cmdline.cc
+++ b/cmdline.cc
@@ -166,6 +166,7 @@ struct custom_option custom_opts[] = {
{ { "macvlan_vs_gw", required_argument, NULL, 0x703 }, "Default GW for the 'vs' interface (e.g. \"192.168.0.1\")" },
{ { "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!" },
};
// clang-format on
@@ -478,6 +479,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
nsjconf->iface_vs_gw = "0.0.0.0";
nsjconf->iface_vs_ma = "";
nsjconf->iface_vs_mo = "private";
+ nsjconf->disable_tsc = false;
nsjconf->orig_uid = getuid();
nsjconf->orig_euid = geteuid();
nsjconf->num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
@@ -856,6 +858,9 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
case 0x706:
nsjconf->iface_vs_mo = parseMACVlanMode(optarg);
break;
+ case 0x707:
+ nsjconf->disable_tsc = true;
+ break;
case 0x801:
nsjconf->cgroup_mem_max = (size_t)strtoull(optarg, NULL, 0);
break;
diff --git a/config.cc b/config.cc
index 620d08e..e9344c9 100644
--- a/config.cc
+++ b/config.cc
@@ -280,6 +280,8 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
nsjconf->iface_vs_ma = njc.macvlan_vs_ma();
nsjconf->iface_vs_mo = njc.macvlan_vs_mo();
+ nsjconf->disable_tsc = njc.disable_tsc();
+
if (njc.has_exec_bin()) {
if (njc.exec_bin().has_path()) {
nsjconf->exec_file = njc.exec_bin().path();
diff --git a/config.proto b/config.proto
index cd297ae..47847cc 100644
--- a/config.proto
+++ b/config.proto
@@ -266,4 +266,6 @@ message NsJailConfig {
/* Binary path (with arguments) to be executed. If not specified here, it
can be specified with cmd-line as "-- /path/to/command arg1 arg2" */
optional Exe exec_bin = 90;
+
+ optional bool disable_tsc = 93 [default = false];
}
diff --git a/contain.cc b/contain.cc
index b5120cc..2ccf333 100644
--- a/contain.cc
+++ b/contain.cc
@@ -119,6 +119,16 @@ static bool containCPU(nsjconf_t* nsjconf) {
return cpu::initCpu(nsjconf);
}
+static bool containTSC(nsjconf_t* nsjconf) {
+ if (nsjconf->disable_tsc) {
+ if (prctl(PR_SET_TSC, PR_TSC_SIGSEGV, 0, 0, 0) == -1) {
+ PLOG_E("prctl(PR_SET_TSC, PR_TSC_SIGSEGV, 0, 0, 0)");
+ return false;
+ }
+ }
+ return true;
+}
+
static bool containSetLimits(nsjconf_t* nsjconf) {
if (nsjconf->disable_rl) {
return true;
@@ -326,6 +336,7 @@ bool containProc(nsjconf_t* nsjconf) {
/* */
/* As non-root */
RETURN_ON_FAILURE(containCPU(nsjconf));
+ RETURN_ON_FAILURE(containTSC(nsjconf));
RETURN_ON_FAILURE(containSetLimits(nsjconf));
RETURN_ON_FAILURE(containPrepareEnv(nsjconf));
RETURN_ON_FAILURE(containMakeFdsCOE(nsjconf));
diff --git a/nsjail.h b/nsjail.h
index 5687ca7..9203143 100644
--- a/nsjail.h
+++ b/nsjail.h
@@ -145,6 +145,7 @@ struct nsjconf_t {
std::string iface_vs_gw;
std::string iface_vs_ma;
std::string iface_vs_mo;
+ bool disable_tsc;
std::string cgroup_mem_mount;
std::string cgroup_mem_parent;
size_t cgroup_mem_max;