Initial support for CLONE_NEWTIME
authorRobert Swiecki <robert@swiecki.net>
Tue, 11 May 2021 12:48:45 +0000 (14:48 +0200)
committerRobert Swiecki <robert@swiecki.net>
Tue, 11 May 2021 12:48:45 +0000 (14:48 +0200)
cmdline.cc
config.cc
config.proto
nsjail.h
subproc.cc

index 574d906126b8a64010fcf836ce01e99c82350fcb..1bb470be76e4882091430ce81496ef1c8fa78eb3 100644 (file)
@@ -122,6 +122,7 @@ struct custom_option custom_opts[] = {
     { { "disable_clone_newipc", no_argument, NULL, 0x0405 }, "Don't use CLONE_NEWIPC" },
     { { "disable_clone_newuts", no_argument, NULL, 0x0406 }, "Don't use CLONE_NEWUTS" },
     { { "disable_clone_newcgroup", no_argument, NULL, 0x0407 }, "Don't use CLONE_NEWCGROUP. Might be required for kernel versions < 4.6" },
+    { { "enable_clone_newtime", no_argument, NULL, 0x0408 }, "Use CLONE_NEWTIME. Supported with kernel versions >= 5.3" },
     { { "uid_mapping", required_argument, NULL, 'U' }, "Add a custom uid mapping of the form inside_uid:outside_uid:count. Setting this requires newuidmap (set-uid) to be present" },
     { { "gid_mapping", required_argument, NULL, 'G' }, "Add a custom gid mapping of the form inside_gid:outside_gid:count. Setting this requires newgidmap (set-uid) to be present" },
     { { "bindmount_ro", required_argument, NULL, 'R' }, "List of mountpoints to be mounted --bind (ro) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'" },
@@ -230,7 +231,7 @@ void logParams(nsjconf_t* nsjconf) {
            "max_conns:%u, max_conns_per_ip:%u, time_limit:%" PRId64
            ", personality:%#lx, daemonize:%s, clone_newnet:%s, "
            "clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, clone_newuts:%s, "
-           "clone_newcgroup:%s, keep_caps:%s, disable_no_new_privs:%s, max_cpus:%zu",
+           "clone_newcgroup:%s, clone_newtime:%s, keep_caps:%s, disable_no_new_privs:%s, max_cpus:%zu",
            nsjconf->hostname.c_str(), nsjconf->chroot.c_str(),
            nsjconf->exec_file.empty() ? nsjconf->argv[0].c_str() : nsjconf->exec_file.c_str(),
            nsjconf->bindhost.c_str(), nsjconf->port, nsjconf->max_conns, nsjconf->max_conns_per_ip,
@@ -238,7 +239,7 @@ void logParams(nsjconf_t* nsjconf) {
            logYesNo(nsjconf->clone_newnet), logYesNo(nsjconf->clone_newuser),
            logYesNo(nsjconf->clone_newns), logYesNo(nsjconf->clone_newpid),
            logYesNo(nsjconf->clone_newipc), logYesNo(nsjconf->clone_newuts),
-           logYesNo(nsjconf->clone_newcgroup), logYesNo(nsjconf->keep_caps),
+           logYesNo(nsjconf->clone_newcgroup), logYesNo(nsjconf->clone_newtime), logYesNo(nsjconf->keep_caps),
            logYesNo(nsjconf->disable_no_new_privs), nsjconf->max_cpus);
 
        for (const auto& p : nsjconf->mountpts) {
@@ -419,6 +420,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
        nsjconf->clone_newipc = true;
        nsjconf->clone_newuts = true;
        nsjconf->clone_newcgroup = true;
+       nsjconf->clone_newcgroup = false;
        nsjconf->mode = MODE_STANDALONE_ONCE;
        nsjconf->is_root_rw = false;
        nsjconf->is_silent = false;
@@ -600,7 +602,7 @@ std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) {
                        nsjconf->clone_newcgroup = false;
                        break;
                case 0x0408:
-                       nsjconf->clone_newcgroup = true;
+                       nsjconf->clone_newtime = true;
                        break;
                case 0x0501:
                        nsjconf->keep_caps = true;
index bf8cee603c4cd9a8d990fdedcf16fd652509f7d2..5dacef6fc61f5b184f680eb93c797618f257be64 100644 (file)
--- a/config.cc
+++ b/config.cc
@@ -183,6 +183,7 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig&
        nsjconf->clone_newipc = njc.clone_newipc();
        nsjconf->clone_newuts = njc.clone_newuts();
        nsjconf->clone_newcgroup = njc.clone_newcgroup();
+       nsjconf->clone_newtime = njc.clone_newtime();
 
        for (ssize_t i = 0; i < njc.uidmap_size(); i++) {
                if (!user::parseId(nsjconf, njc.uidmap(i).inside_id(), njc.uidmap(i).outside_id(),
index 6b03dcf1550227c886e425060b56dbe24b28dac7..128d383ec61b6fee55e65e54958f373fe1d4a9b8 100644 (file)
@@ -177,6 +177,8 @@ message NsJailConfig {
     optional bool clone_newuts = 52 [default = true];
     /* Disable for kernel versions < 4.6 as it's not supported there */
     optional bool clone_newcgroup = 53 [default = true];
+       /* Supported with kernel versions >= 5.3 */
+    optional bool clone_newtime = 86 [default = false];
 
     /* Mappings for UIDs and GIDs. See the description for 'msg IdMap'
        for more */
index 038a62eea623589b13c36e5960cfab6655e6fd63..5e686c7bf3bec21040f5503cb71d5a4dbb79baf7 100644 (file)
--- a/nsjail.h
+++ b/nsjail.h
@@ -124,6 +124,7 @@ struct nsjconf_t {
        bool clone_newipc;
        bool clone_newuts;
        bool clone_newcgroup;
+       bool clone_newtime;
        enum ns_mode_t mode;
        bool is_root_rw;
        bool is_silent;
index dd39fa114f751443e27fa7ea6432b0b2c1d99c71..154e4b771ab9bfd44a059a85af4512959ef3118b 100644 (file)
@@ -59,6 +59,9 @@ namespace subproc {
 #if !defined(CLONE_NEWCGROUP)
 #define CLONE_NEWCGROUP 0x02000000
 #endif /* !defined(CLONE_NEWCGROUP) */
+#if !defined(CLONE_NEWTIME)
+#define #define CLONE_NEWTIME 0x00000080
+#endif /* !defined(CLONE_NEWTIME) */
 
 static const std::string cloneFlagsToStr(uintptr_t flags) {
        std::string res;
@@ -67,6 +70,7 @@ static const std::string cloneFlagsToStr(uintptr_t flags) {
                const uintptr_t flag;
                const char* const name;
        } static const cloneFlags[] = {
+               NS_VALSTR_STRUCT(CLONE_NEWTIME),
                NS_VALSTR_STRUCT(CLONE_VM),
                NS_VALSTR_STRUCT(CLONE_FS),
                NS_VALSTR_STRUCT(CLONE_FILES),
@@ -430,6 +434,7 @@ pid_t runChild(nsjconf_t* nsjconf, int netfd, int fd_in, int fd_out, int fd_err)
        flags |= (nsjconf->clone_newipc ? CLONE_NEWIPC : 0);
        flags |= (nsjconf->clone_newuts ? CLONE_NEWUTS : 0);
        flags |= (nsjconf->clone_newcgroup ? CLONE_NEWCGROUP : 0);
+       flags |= (nsjconf->clone_newtime ? CLONE_NEWTIME : 0);
 
        if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
                if (unshare(flags) == -1) {