"max_conns_per_ip:%u, uid:(ns:%u, global:%u), gid:(ns:%u, global:%u), time_limit:%ld, personality:%#lx, daemonize:%s, "
"clone_newnet:%s, clone_newuser:%s, clone_newns:%s, clone_newpid:%s, "
"clone_newipc:%s, clonew_newuts:%s, clone_newcgroup:%s, apply_sandbox:%s, keep_caps:%s, "
- "tmpfs_size:%zu, disable_no_new_privs:%s",
+ "tmpfs_size:%zu, disable_no_new_privs:%s, pivot_root_only:%s",
nsjconf->hostname, nsjconf->chroot, nsjconf->argv[0], nsjconf->bindhost, nsjconf->port,
nsjconf->max_conns_per_ip, nsjconf->inside_uid, nsjconf->outside_uid,
nsjconf->inside_gid, nsjconf->outside_gid, nsjconf->tlimit, nsjconf->personality,
logYesNo(nsjconf->clone_newpid), logYesNo(nsjconf->clone_newipc),
logYesNo(nsjconf->clone_newuts), logYesNo(nsjconf->clone_newcgroup),
logYesNo(nsjconf->apply_sandbox), logYesNo(nsjconf->keep_caps), nsjconf->tmpfs_size,
- logYesNo(nsjconf->disable_no_new_privs));
+ logYesNo(nsjconf->disable_no_new_privs), logYesNo(nsjconf->pivot_root_only));
{
struct mounts_t *p;
.daemonize = false,
.tlimit = 0,
.apply_sandbox = true,
+ .pivot_root_only = false,
.verbose = false,
.keep_caps = false,
.disable_no_new_privs = false,
{{"disable_sandbox", no_argument, NULL, 0x0503}, "Don't enable the seccomp-bpf sandboxing"},
{{"skip_setsid", no_argument, NULL, 0x0504}, "Don't call setsid(), allows for terminal signal handling in the sandboxed process"},
{{"pass_fd", required_argument, NULL, 0x0505}, "Don't close this FD before executing child (can be specified multiple times), by default: 0/1/2 are kept open"},
+ {{"pivot_root_only", no_argument, NULL, 0x0506}, "Only perform pivot_root, no chroot. This will enable nested namespaces"},
{{"disable_no_new_privs", no_argument, NULL, 0x0507}, "Don't set the prctl(NO_NEW_PRIVS, 1) (DANGEROUS)"},
{{"rlimit_as", required_argument, NULL, 0x0201}, "RLIMIT_AS in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 512)"},
{{"rlimit_core", required_argument, NULL, 0x0202}, "RLIMIT_CORE in MB, 'max' for RLIM_INFINITY, 'def' for the current value (default: 0)"},
TAILQ_INSERT_HEAD(&nsjconf->open_fds, f, pointers);
}
break;
+ case 0x0506:
+ nsjconf->pivot_root_only = true;
+ break;
case 0x0507:
nsjconf->disable_no_new_privs = true;
break;
return false;
}
- const char *const newrootdir = "/new_root";
- if (mkdir(newrootdir, 0755) == -1) {
- PLOG_E("mkdir('%s')", newrootdir);
- return false;
+ const char *newrootdir;
+ if (nsjconf->pivot_root_only == false) {
+ newrootdir = "/new_root";
+ if (mkdir(newrootdir, 0755) == -1) {
+ PLOG_E("mkdir('%s')", newrootdir);
+ return false;
+ }
+ } else {
+ newrootdir = "/";
}
struct mounts_t *p;
PLOG_E("umount2('/old_root', MNT_DETACH)");
return false;
}
- if (chroot(newrootdir) == -1) {
- PLOG_E("chroot('%s')", newrootdir);
- return false;
+ if (nsjconf->pivot_root_only == false) {
+ if (chroot(newrootdir) == -1) {
+ PLOG_E("chroot('%s')", newrootdir);
+ return false;
+ }
}
if (chdir(nsjconf->cwd) == -1) {