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)]: :'