config: allow to use soft/hard/inf limits for rlimits

This commit is contained in:
Robert Swiecki 2017-10-06 22:44:27 +02:00
parent ee3d454457
commit dbc6fab582
5 changed files with 54 additions and 18 deletions

View File

@ -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,

View File

@ -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;

View 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 ];

View 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

View File

@ -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 */