Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions cmdline.cc
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ static const struct custom_option custom_opts[] = {
{ { "use_core_scheduling", no_argument, nullptr, 0x709 }, "Enable Linux core scheduling (PR_SCHED_CORE, requires kernel >= 5.14)" },
{ { "user_net", no_argument, nullptr, 0x70A }, "Enable user-mode networking (nstun backend)" },
{ { "oom_score_adj", required_argument, nullptr, 0x800 }, "OOM score adjustment for the sandbox (-1000 to 1000) (default: not set)" },
{ { "init", no_argument, NULL, 0x907 }, "Run an init process inside the container. Incompatible with disable_clone_newpid and with RERUN and LISTEN modes. Implicitly enabled in EXECVE mode unless disable_clone_newpid is also provided." },

};
// clang-format on

Expand Down Expand Up @@ -992,6 +994,9 @@ std::unique_ptr<nsj_t> parseArgs(int argc, char* argv[]) {
case 0x800:
nsj->njc.set_oom_score_adj((int32_t)strtol(optarg, NULL, 0));
break;
case 0x907:
nsj->njc.set_init(true);
break;
default:
cmdlineUsage(argv[0]);
return nullptr;
Expand All @@ -1015,6 +1020,21 @@ std::unique_ptr<nsj_t> parseArgs(int argc, char* argv[]) {
LOG_F("cannot set both cgroup_mem_memsw_max and cgroup_mem_swap_max");
}

if (nsj->njc.init()) {
if (nsj->njc.mode() == nsjail::Mode::LISTEN ||
nsj->njc.mode() == nsjail::Mode::RERUN) {
LOG_F("cannot enable init process with mode LISTEN or RERUN");
}
if (!nsj->njc.clone_newpid()) {
LOG_F("cannot enable init process with disable_clone_newpid");
}
}

if (nsj->njc.mode() == nsjail::Mode::EXECVE && nsj->njc.clone_newpid()) {
nsj->njc.set_init(true);
LOG_D("enabling init process for execve mode");
}

return nsj;
}

Expand Down
3 changes: 3 additions & 0 deletions config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,9 @@ 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 = 98;

/* Run an init process inside the container. */
optional bool init = 102 [default = false];
}

// vim: set noexpandtab ts=4 sw=4:
31 changes: 18 additions & 13 deletions pid.cc
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,9 @@

namespace pid {

bool initNs(nsj_t* nsj) {
if (nsj->njc.mode() != nsjail::Mode::EXECVE) {
return true;
}
if (!nsj->njc.clone_newpid()) {
return true;
}

bool newInitProc() {
LOG_D("Creating a dummy 'init' process");

/*
* If -Me is used then we need to create permanent init inside PID ns, otherwise only the
* first clone/fork will work, and the rest will fail with ENOMEM (see 'man pid_namespaces'
* for details on this behavior)
*/
pid_t pid = subproc::cloneProc(CLONE_FS, 0);
if (pid == -1) {
PLOG_E("Couldn't create a dummy init process");
Expand Down Expand Up @@ -84,4 +72,21 @@ bool initNs(nsj_t* nsj) {
}
}

bool initNs(nsj_t* nsj) {
if (nsj->njc.mode() != nsjail::Mode::EXECVE) {
return true;
}
if (!nsj->njc.init()) {
return true;
}

/*
* If -Me is used then we need to create permanent init inside PID ns, otherwise only the
* first clone/fork will work, and the rest will fail with ENOMEM (see 'man pid_namespaces'
* for details on this behavior)
*/

return newInitProc();
}

} // namespace pid
1 change: 1 addition & 0 deletions pid.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@

namespace pid {

bool newInitProc();
bool initNs(nsj_t* nsj);

} // namespace pid
Expand Down
13 changes: 13 additions & 0 deletions subproc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#include "macros.h"
#include "net.h"
#include "nstun/nstun.h"
#include "pid.h"
#include "sandbox.h"
#include "unotify/unotify.h"
#include "user.h"
Expand Down Expand Up @@ -535,6 +536,18 @@ pid_t runChild(nsj_t* nsj, int netfd, int fd_in, int fd_out, int fd_err) {
LOG_D("Creating new process with clone flags:%s and exit_signal:SIGCHLD",
cloneFlagsToStr(flags).c_str());

if (nsj->njc.init() && nsj->njc.mode() == nsjail::Mode::ONCE) {
LOG_D("unshare(flags: %s)", cloneFlagsToStr(flags).c_str());
if (unshare(flags) == -1) {
PLOG_F("unshare(%s)", cloneFlagsToStr(flags).c_str());
}
if (!pid::newInitProc()) {
return -1;
}
// Clear clone flags as they have already been applied by unshare()
flags = 0;
}

int sv[2];
if (socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sv) == -1) {
PLOG_E("socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC) failed");
Expand Down