diff --git a/bubblewrap.c b/bubblewrap.c index 2ab88d2f..8b61dba3 100644 --- a/bubblewrap.c +++ b/bubblewrap.c @@ -75,6 +75,7 @@ static bool opt_unshare_uts = false; static bool opt_unshare_cgroup = false; static bool opt_unshare_cgroup_try = false; static bool opt_needs_devpts = false; +static bool opt_new_pgrp = false; static bool opt_new_session = false; static bool opt_die_with_parent = false; static uid_t opt_sandbox_uid = -1; @@ -350,6 +351,7 @@ usage (int ecode, FILE *out) " --userns-block-fd FD Block on FD until the user namespace is ready\n" " --info-fd FD Write information about the running container to FD\n" " --json-status-fd FD Write container status to FD as multiple JSON documents\n" + " --new-pgrp Create a new process group\n" " --new-session Create a new terminal session\n" " --die-with-parent Kills with SIGKILL child process (COMMAND) when bwrap or bwrap's parent dies.\n" " --as-pid-1 Do not install a reaper process with PID=1\n" @@ -2567,6 +2569,10 @@ parse_args_recurse (int *argcp, argv += 1; argc -= 1; } + else if (strcmp (arg, "--new-pgrp") == 0) + { + opt_new_pgrp = true; + } else if (strcmp (arg, "--new-session") == 0) { opt_new_session = true; @@ -3468,9 +3474,22 @@ main (int argc, xsetenv ("PWD", new_cwd, 1); free (old_cwd); - if (opt_new_session && - setsid () == (pid_t) -1) - die_with_error ("setsid"); + if (opt_new_session) + { + if (setsid () == (pid_t) -1) + die_with_error ("setsid"); + + /* The session ID, process group ID and process ID are all equal + * for a session leader */ + debug ("became session leader, pgid %d in sandbox", getpgid (0)); + } + else if (opt_new_pgrp) + { + if (setpgid (0, 0) == -1) + die_with_error ("setpgid(0, 0)"); + + debug ("became process group leader, pgid %d in sandbox", getpgid (0)); + } if (label_exec (opt_exec_label) == -1) die_with_error ("label_exec %s", argv[0]); diff --git a/bwrap.xml b/bwrap.xml index b48cf5b4..32b30baf 100644 --- a/bwrap.xml +++ b/bwrap.xml @@ -583,6 +583,37 @@ (see CVE-2017-5226). + + + + + + + Create a new process group for the sandbox + (calls + + setpgid + 2 + ). + Ignored if combined with , + because creating a new terminal session always creates a new + process group as a side-effect. + + + Note that if neither + nor is used, + the sandboxed process is likely to be able to kill processes + outside its process ID namespace by using + kill (0, SIGTERM) + to signal its entire process group. + In this case, + the parent process invoking bwrap needs to + ensure that this will not cause denial of service, + for example by placing bwrap in a new + process group. + + + diff --git a/completions/bash/bwrap b/completions/bash/bwrap index e7a523c2..b6cced36 100644 --- a/completions/bash/bwrap +++ b/completions/bash/bwrap @@ -14,6 +14,7 @@ _bwrap() { --clearenv --disable-userns --help + --new-pgrp --new-session --unshare-all --unshare-cgroup diff --git a/completions/zsh/_bwrap b/completions/zsh/_bwrap index fbddda43..e1cf9f13 100644 --- a/completions/zsh/_bwrap +++ b/completions/zsh/_bwrap @@ -53,6 +53,7 @@ _bwrap_args=( '--json-status-fd[Write container status to FD as multiple JSON documents]: :_guard "[0-9]#" "file descriptor to write to"' '--lock-file[Take a lock on DEST while sandbox is running]:lock file:_files' '--mqueue[Mount new mqueue on DEST]:mount point for mqueue:_files -/' + '--new-pgrp[Create a new process group]' '--new-session[Create a new terminal session]' '--perms[Set permissions for next action argument]: :_guard "[0-7]#" "permissions in octal": :->after_perms' '--pidns[Use this user namespace (as parent namespace if using --unshare-pid)]: :'