case MODE_STANDALONE_ONCE:
LOG_I("Mode: STANDALONE_ONCE");
break;
+ case MODE_STANDALONE_EXECVE:
+ LOG_I("Mode: STANDALONE_EXECVE");
+ break;
case MODE_STANDALONE_RERUN:
LOG_I("Mode: STANDALONE_RERUN");
break;
.initial_gid = getgid(),
.max_conns_per_ip = 0,
.tmpfs_size = 4 * (1024 * 1024),
+ .mount_proc = true,
};
/* *INDENT-OFF* */
{{"help", no_argument, NULL, 'h'}, "Help plz.."},
{{"mode", required_argument, NULL, 'M'}, "Execution mode (default: l [MODE_LISTEN_TCP]):\n"
"\tl: Listen to connections on a TCP port (specified with --port) [MODE_LISTEN_TCP]\n"
- "\to: Immediately launch a single process on a console [MODE_STANDALONE_ONCE]\n"
+ "\to: Immediately launch a single process on a console using clone/execve [MODE_STANDALONE_ONCE]\n"
+ "\te: Immediately launch a single process on a console using execve [MODE_STANDALONE_EXECVE]\n"
"\tr: Immediately launch a single process on a console, keep doing it forever [MODE_STANDALONE_RERUN]"},
{{"chroot", required_argument, NULL, 'c'}, "Directory containing / of the jail (default: '/chroot')"},
{{"user", required_argument, NULL, 'u'}, "Username/uid of processess inside the jail (default: 'nobody')"},
{{"daemon", no_argument, NULL, 'd'}, "Daemonize after start? (default: false)"},
{{"verbose", no_argument, NULL, 'v'}, "Verbose output (default: false)"},
{{"keep_env", no_argument, NULL, 'e'}, "Should all environment variables be passed to the child? (default: false)"},
- {{"keep_caps", no_argument, NULL, 0x0502}, "Don't drop capabilities (DANGEROUS) (default: false)"},
+ {{"keep_caps", no_argument, NULL, 0x0501}, "Don't drop capabilities (DANGEROUS) (default: false)"},
+ {{"silent", no_argument, NULL, 0x0502}, "Redirect child's fd:0/1/2 to /dev/null (default: false)"},
+ {{"disable_sandbox", no_argument, NULL, 0x0503}, "Don't enable the seccomp-bpf sandboxing (default: false)"},
{{"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)"},
{{"rlimit_cpu", required_argument, NULL, 0x0203}, "RLIMIT_CPU, 'max' for RLIM_INFINITY, 'def' for the current value (default: 600)"},
{{"disable_clone_newpid", no_argument, NULL, 0x0404}, "Don't use CLONE_NEWPID (default: false)"},
{{"disable_clone_newipc", no_argument, NULL, 0x0405}, "Don't use CLONE_NEWIPC (default: false)"},
{{"disable_clone_newuts", no_argument, NULL, 0x0406}, "Don't use CLONE_NEWUTS (default: false)"},
- {{"disable_sandbox", no_argument, NULL, 0x0501}, "Don't enable the seccomp-bpf sandboxing (default: false)"},
- {{"rw", no_argument, NULL, 0x0503}, "Mount / as RW (default: RO)"},
- {{"silent", no_argument, NULL, 0x0504}, "Redirect child's fd:0/1/2 to /dev/null (default: false)"},
+ {{"rw", no_argument, NULL, 0x0601}, "Mount / as RW (default: RO)"},
{{"bindmount_ro", required_argument, NULL, 'R'}, "List of mountpoints to be mounted --bind (ro) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'. (default: none)"},
{{"bindmount", required_argument, NULL, 'B'}, "List of mountpoints to be mounted --bind (rw) inside the container. Can be specified multiple times. Supports 'source' syntax, or 'source:dest'. (default: none)"},
{{"tmpfsmount", required_argument, NULL, 'T'}, "List of mountpoints to be mounted as RW/tmpfs inside the container. Can be specified multiple times. Supports 'dest' syntax. (default: none)"},
{{"iface", required_argument, NULL, 'I'}, "Interface which will be cloned (MACVTAP) and put inside the subprocess' namespace"},
- {{"tmpfs_size", required_argument, NULL, 0x0506}, "Number of bytes to allocate for tmpfsmounts in bytes (default: 4194304)"},
+ {{"tmpfs_size", required_argument, NULL, 0x0602}, "Number of bytes to allocate for tmpfsmounts (default: 4194304)"},
+ {{"disable_proc", no_argument, NULL, 0x0603}, "Disable mounting /proc (default: false)"},
{{0, 0, 0, 0}, NULL},
};
/* *INDENT-ON* */
case 'i':
nsjconf->max_conns_per_ip = strtoul(optarg, NULL, 0);
break;
- case 0x0506:
- nsjconf->tmpfs_size = strtoull(optarg, NULL, 0);
- break;
case 'u':
user = optarg;
break;
nsjconf->clone_newuts = false;
break;
case 0x0501:
- nsjconf->apply_sandbox = false;
+ nsjconf->keep_caps = true;
break;
case 0x0502:
- nsjconf->keep_caps = true;
+ nsjconf->is_silent = true;
break;
case 0x0503:
+ nsjconf->apply_sandbox = false;
+ break;
+ case 0x0601:
nsjconf->is_root_rw = true;
break;
- case 0x0504:
- nsjconf->is_silent = true;
+ case 0x0602:
+ nsjconf->tmpfs_size = strtoull(optarg, NULL, 0);
+ break;
+ case 0x0603:
+ nsjconf->mount_proc = false;
break;
case 'R':
{
case 'o':
nsjconf->mode = MODE_STANDALONE_ONCE;
break;
+ case 'e':
+ nsjconf->mode = MODE_STANDALONE_EXECVE;
+ break;
case 'r':
nsjconf->mode = MODE_STANDALONE_RERUN;
break;
return success;
}
+static bool containMountProc(struct nsjconf_t *nsjconf, const char *newrootdir)
+{
+ char procrootdir[PATH_MAX];
+ snprintf(procrootdir, sizeof(procrootdir), "%s/proc", newrootdir);
+
+ if (nsjconf->mount_proc == false) {
+ return true;
+ }
+
+ if (nsjconf->mode == MODE_STANDALONE_EXECVE) {
+ if (mount("/proc", procrootdir, NULL, MS_REC | MS_BIND, NULL) == -1) {
+ PLOG_E("mount('/proc', '%s', MS_REC|MS_BIND)", procrootdir);
+ return false;
+ }
+ return true;
+ }
+ if (mount(NULL, procrootdir, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL) == -1) {
+ PLOG_E("mount('%s', 'proc')", procrootdir);
+ return false;
+ }
+
+ return true;
+}
+
bool containMountFS(struct nsjconf_t * nsjconf)
{
const char *destdir = "/tmp";
PLOG_E("mount('%s', '%s', MS_BIND | MS_REC)", nsjconf->chroot, newrootdir);
return false;
}
-
- char procrootdir[PATH_MAX];
- snprintf(procrootdir, sizeof(procrootdir), "%s/proc", newrootdir);
- if (mount(NULL, procrootdir, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL) == -1) {
- PLOG_E("mount('%s', 'proc')", procrootdir);
+ if (containMountProc(nsjconf, newrootdir) == false) {
return false;
}
bool containSetupFD(struct nsjconf_t * nsjconf, int fd_in, int fd_out, int fd_err, int fd_log)
{
/* Make sure all logs go to the parent process from now on */
- logRedirectLogFD(fd_log);
+ if (fd_log != -1) {
+ logRedirectLogFD(fd_log);
+ }
if (nsjconf->mode != MODE_LISTEN_TCP) {
if (nsjconf->is_silent == false) {