diff --git a/cmdline.cc b/cmdline.cc index 051619d..813f4b9 100644 --- a/cmdline.cc +++ b/cmdline.cc @@ -109,6 +109,9 @@ struct custom_option custom_opts[] = { { { "rlimit_nofile", required_argument, NULL, 0x0205 }, "RLIMIT_NOFILE, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 32)" }, { { "rlimit_nproc", required_argument, NULL, 0x0206 }, "RLIMIT_NPROC, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 'soft')" }, { { "rlimit_stack", required_argument, NULL, 0x0207 }, "RLIMIT_STACK in MB, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 'soft')" }, + { { "rlimit_memlock", required_argument, NULL, 0x0209 }, "RLIMIT_MEMLOCK in KB, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 'soft')" }, + { { "rlimit_rtprio", required_argument, NULL, 0x0210 }, "RLIMIT_RTPRIO, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 'soft')" }, + { { "rlimit_msgqueue", required_argument, NULL, 0x0211 }, "RLIMIT_MSGQUEUE in bytes, 'max' or 'hard' for the current hard limit, 'def' or 'soft' for the current soft limit, 'inf' for RLIM64_INFINITY (default: 'soft')" }, { { "disable_rlimits", no_argument, NULL, 0x0208 }, "Disable all rlimits, default to limits set by parent" }, { { "persona_addr_compat_layout", no_argument, NULL, 0x0301 }, "personality(ADDR_COMPAT_LAYOUT)" }, { { "persona_mmap_page_zero", no_argument, NULL, 0x0302 }, "personality(MMAP_PAGE_ZERO)" }, @@ -426,6 +429,9 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { nsjconf->rl_nofile = 32ULL; nsjconf->rl_nproc = parseRLimit(RLIMIT_NPROC, "soft", 1); nsjconf->rl_stack = parseRLimit(RLIMIT_STACK, "soft", 1); + nsjconf->rl_mlock = parseRLimit(RLIMIT_MEMLOCK, "soft", 1); + nsjconf->rl_rtpr = parseRLimit(RLIMIT_RTPRIO, "soft", 1); + nsjconf->rl_msgq = parseRLimit(RLIMIT_MSGQUEUE, "soft", 1); nsjconf->disable_rl = false; nsjconf->personality = 0; nsjconf->clone_newnet = true; @@ -578,6 +584,15 @@ std::unique_ptr parseArgs(int argc, char* argv[]) { case 0x0207: nsjconf->rl_stack = parseRLimit(RLIMIT_STACK, optarg, (1024 * 1024)); break; + case 0x0209: + nsjconf->rl_mlock = parseRLimit(RLIMIT_MEMLOCK, optarg, 1024); + break; + case 0x0210: + nsjconf->rl_rtpr = parseRLimit(RLIMIT_RTPRIO, optarg, 1); + break; + case 0x0211: + nsjconf->rl_msgq = parseRLimit(RLIMIT_MSGQUEUE, optarg, 1); + break; case 0x0208: nsjconf->disable_rl = true; break; diff --git a/config.cc b/config.cc index 413f6fc..40b7425 100644 --- a/config.cc +++ b/config.cc @@ -158,6 +158,11 @@ static bool configParseInternal(nsjconf_t* nsjconf, const nsjail::NsJailConfig& 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); + nsjconf->rl_mlock = configRLimit( + RLIMIT_MEMLOCK, njc.rlimit_memlock_type(), njc.rlimit_memlock(), 1024UL); + nsjconf->rl_rtpr = configRLimit(RLIMIT_RTPRIO, njc.rlimit_rtprio_type(), njc.rlimit_rtprio()); + nsjconf->rl_msgq = configRLimit(RLIMIT_MSGQUEUE, njc.rlimit_msgqueue_type(), njc.rlimit_msgqueue()); + nsjconf->disable_rl = njc.disable_rl(); if (njc.persona_addr_compat_layout()) { diff --git a/config.proto b/config.proto index 8c55991..95bfa59 100644 --- a/config.proto +++ b/config.proto @@ -157,6 +157,13 @@ message NsJailConfig { /* In MiB, use the soft limit value by default */ optional uint64 rlimit_stack = 40 [default = 8]; optional RLimit rlimit_stack_type = 41 [default = SOFT]; + /* In KB, use the soft limit value by default */ + optional uint64 rlimit_memlock = 88 [default = 64]; + optional RLimit rlimit_memlock_type = 89 [default = SOFT]; + optional uint64 rlimit_rtprio = 90 [default = 0]; + optional RLimit rlimit_rtprio_type = 91 [default = SOFT]; + optional uint64 rlimit_msgqueue = 92 [default = 1024]; /* In bytes */ + optional RLimit rlimit_msgqueue_type = 93 [default = SOFT]; /* Disable all rlimits, default to limits set by parent */ optional bool disable_rl = 84 [default = false]; diff --git a/contain.cc b/contain.cc index e1c337b..db741a5 100644 --- a/contain.cc +++ b/contain.cc @@ -160,6 +160,21 @@ static bool containSetLimits(nsjconf_t* nsjconf) { PLOG_E("setrlimit64(0, RLIMIT_STACK, %" PRIu64 ")", nsjconf->rl_stack); return false; } + rl.rlim_cur = rl.rlim_max = nsjconf->rl_mlock; + if (setrlimit64(RLIMIT_MEMLOCK, &rl) == -1) { + PLOG_E("setrlimit64(0, RLIMIT_MEMLOCK, %" PRIu64 ")", nsjconf->rl_mlock); + return false; + } + rl.rlim_cur = rl.rlim_max = nsjconf->rl_rtpr; + if (setrlimit64(RLIMIT_RTPRIO, &rl) == -1) { + PLOG_E("setrlimit64(0, RLIMIT_RTPRIO, %" PRIu64 ")", nsjconf->rl_rtpr); + return false; + } + rl.rlim_cur = rl.rlim_max = nsjconf->rl_msgq; + if (setrlimit64(RLIMIT_MSGQUEUE , &rl) == -1) { + PLOG_E("setrlimit64(0, RLIMIT_MSGQUEUE , %" PRIu64 ")", nsjconf->rl_msgq); + return false; + } return true; } diff --git a/nsjail.h b/nsjail.h index 7dd588e..589f350 100644 --- a/nsjail.h +++ b/nsjail.h @@ -115,6 +115,9 @@ struct nsjconf_t { uint64_t rl_nofile; uint64_t rl_nproc; uint64_t rl_stack; + uint64_t rl_mlock; + uint64_t rl_rtpr; + uint64_t rl_msgq; bool disable_rl; unsigned long personality; bool clone_newnet;