config: allow to use soft/hard/inf limits for rlimits
authorRobert Swiecki <robert@swiecki.net>
Fri, 6 Oct 2017 20:44:27 +0000 (22:44 +0200)
committerRobert Swiecki <robert@swiecki.net>
Fri, 6 Oct 2017 20:44:27 +0000 (22:44 +0200)
cmdline.c
config.cc
config.proto
configs/bash-with-fake-geteuid.cfg
contain.h

index 9f42786850086b240f3517e40961de5a692854be..f7c35ba1ccf06edec5f0fde4c817c4154f5eb800 100644 (file)
--- a/cmdline.c
+++ b/cmdline.c
@@ -257,11 +257,14 @@ __rlim64_t cmdlineParseRLimit(int res, const char *optarg, unsigned long mul)
        if (getrlimit64(res, &cur) == -1) {
                PLOG_F("getrlimit(%d)", res);
        }
-       if (strcasecmp(optarg, "max") == 0) {
+       if (strcasecmp(optarg, "def") == 0 || strcasecmp(optarg, "soft") == 0) {
+               return cur.rlim_cur;
+       }
+       if (strcasecmp(optarg, "max") == 0 || strcasecmp(optarg, "hard")) {
                return cur.rlim_max;
        }
-       if (strcasecmp(optarg, "def") == 0) {
-               return cur.rlim_cur;
+       if (strcasecmp(optarg, "inf") == 0) {
+               return RLIM64_INFINITY;
        }
        if (utilIsANumber(optarg) == false) {
                LOG_F("RLIMIT %d needs a numeric or 'max'/'def' value ('%s' provided)", res,
index c6c84ff5873f4c87aeb28b6c9078c155d668d031..4d13176e9714dc3eec1985fd598e2598fbc87794 100644 (file)
--- a/config.cc
+++ b/config.cc
@@ -30,6 +30,7 @@ extern "C" {
 #include <sys/types.h>
 
 #include "caps.h"
+#include "cmdline.h"
 #include "config.h"
 #include "log.h"
 #include "mount.h"
@@ -46,6 +47,24 @@ extern "C" {
 
 #define DUP_IF_SET(njc, val) (njc.has_##val() ? utilStrDup(njc.val().c_str()) : NULL)
 
+static __rlim64_t configRLimit(int res, const nsjail::RLimit& rl, const uint64_t val, unsigned long mul = 1UL)
+{
+    if (rl == nsjail::RLimit::VALUE) {
+        return (val * mul);
+    }
+    if (rl == nsjail::RLimit::SOFT) {
+        return cmdlineParseRLimit(res, "soft", mul);
+    }
+    if (rl == nsjail::RLimit::HARD) {
+        return cmdlineParseRLimit(res, "hard", mul);
+    }
+    if (rl == nsjail::RLimit::INF) {
+        return RLIM64_INFINITY;
+    }
+    LOG_F("Unknown rlimit value type for rlimit:%d", res);
+    abort();
+}
+
 static bool configParseInternal(struct nsjconf_t* nsjconf,
     const nsjail::NsJailConfig& njc)
 {
@@ -138,17 +157,13 @@ static bool configParseInternal(struct nsjconf_t* nsjconf,
 
     nsjconf->disable_no_new_privs = njc.disable_no_new_privs();
 
-    nsjconf->rl_as = njc.rlimit_as() * 1024ULL * 1024ULL;
-    nsjconf->rl_core = njc.rlimit_core() * 1024ULL * 1024ULL;
-    nsjconf->rl_cpu = njc.rlimit_cpu();
-    nsjconf->rl_fsize = njc.rlimit_fsize() * 1024ULL * 1024ULL;
-    nsjconf->rl_nofile = njc.rlimit_nofile();
-    if (njc.has_rlimit_nproc()) {
-        nsjconf->rl_nproc = njc.rlimit_nproc();
-    }
-    if (njc.has_rlimit_stack()) {
-        nsjconf->rl_stack = njc.rlimit_stack() * 1024ULL * 1024ULL;
-    }
+    nsjconf->rl_as = configRLimit(RLIMIT_AS, njc.rlimit_as_type(), njc.rlimit_as(), 1024UL * 1024UL);
+    nsjconf->rl_core = configRLimit(RLIMIT_CORE, njc.rlimit_core_type(), njc.rlimit_core(), 1024UL * 1024UL);
+    nsjconf->rl_cpu = configRLimit(RLIMIT_CPU, njc.rlimit_cpu_type(), njc.rlimit_cpu());
+    nsjconf->rl_fsize = configRLimit(RLIMIT_FSIZE, njc.rlimit_fsize_type(), njc.rlimit_fsize(), 1024UL * 1024UL);
+    nsjconf->rl_nofile = configRLimit(RLIMIT_NOFILE, njc.rlimit_nofile_type(), njc.rlimit_nofile());
+    nsjconf->rl_nproc = configRLimit(RLIMIT_NPROC, njc.rlimit_nproc_type(), njc.rlimit_nproc());
+    nsjconf->rl_stack = configRLimit(RLIMIT_STACK, njc.rlimit_stack_type(), njc.rlimit_stack(), 1024UL * 1024UL);
 
     if (njc.persona_addr_compat_layout()) {
         nsjconf->personality |= ADDR_COMPAT_LAYOUT;
index e23c29d4470c053c4a29a9fed66e9a0c5f12a4b0..b7e8c7e48618256738f607673be364ed1dfc61cf 100644 (file)
@@ -54,6 +54,12 @@ message MountPt
     /* Is it a symlink (instead of real mount point)? */
     optional bool is_symlink = 12 [ default = false ];
 }
+enum RLimit {
+    VALUE = 0; /* Use the provided value */
+    SOFT = 1; /* Use current soft rlimit */
+    HARD = 2; /* Use current hard rlimit */
+    INF = 3; /* Use RLIM64_INFINITY */
+}
 message Exe
 {
     /* Will be used both as execv's path and as argv[0] */
@@ -126,13 +132,24 @@ message NsJailConfig
        inside the jail */
     optional bool disable_no_new_privs = 25 [ default = false ];
 
+       /* Various rlimits, the rlimit_as/rlimit_core/... are used only if
+       rlimit_as_type/rlimit_core_type/... are set to RLimit::VALUE */
     optional uint64 rlimit_as = 26 [ default = 512 ]; /* In MiB */
+    optional RLimit rlimit_as_type = 64 [ default = VALUE ];
     optional uint64 rlimit_core = 27 [ default = 0 ]; /* In MiB */
+    optional RLimit rlimit_core_type = 65 [ default = VALUE ];
     optional uint64 rlimit_cpu = 28 [ default = 600 ]; /* In seconds */
+    optional RLimit rlimit_cpu_type = 66 [ default = VALUE ];
     optional uint64 rlimit_fsize = 29 [ default = 1 ]; /* In MiB */
+    optional RLimit rlimit_fsize_type = 67 [ default = VALUE ];
     optional uint64 rlimit_nofile = 30 [ default = 32 ];
-    optional uint64 rlimit_nproc = 31; /* This is system-wide: tricky to use */
-    optional uint64 rlimit_stack = 32; /* In MiB */
+    optional RLimit rlimit_nofile_type = 68 [ default = VALUE ];
+    /* RLIMIT_NPROC is system-wide - tricky to use; use the soft limit value by default here */
+    optional uint64 rlimit_nproc = 31 [ default = 1024 ];
+    optional RLimit rlimit_nproc_type = 69 [ default = SOFT ];
+    /* In MiB, use the soft limit value by default */
+    optional uint64 rlimit_stack = 32 [ default = 1048576 ];
+    optional RLimit rlimit_stack_type = 70 [ default = SOFT ];
 
     /* See 'man personality' for more */
     optional bool persona_addr_compat_layout = 33 [ default = false ];
index 1f4cae74a7279aa434aace4073846d533c3320a6..9241af570c63b96926d1ac184db70bc8ab6394da 100644 (file)
@@ -40,7 +40,8 @@ rlimit_core: 0
 rlimit_cpu: 10
 rlimit_fsize: 0
 rlimit_nofile: 32
-rlimit_stack: 1
+rlimit_stack_type: SOFT
+rlimit_nproc_type: SOFT
 
 persona_addr_compat_layout: false
 persona_mmap_page_zero: false
index 31c871484107992321a32c756444e3330d0f3d7d..edba108cc362850dd01c305132d0457356fea549 100644 (file)
--- a/contain.h
+++ b/contain.h
@@ -26,7 +26,7 @@
 
 #include "common.h"
 
-bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err);
+bool containSetupFD(struct nsjconf_t *nsjconf, int fd_in, int fd_out, int fd_err);
 bool containContain(struct nsjconf_t *nsjconf);
 
 #endif                         /* NS_CONTAIN_H */