diff options
author | Simon McVittie <smcv@collabora.com> | 2022-12-16 18:46:23 +0000 |
---|---|---|
committer | Alexander Larsson <alexander.larsson@gmail.com> | 2023-01-03 11:04:09 +0100 |
commit | b5f672355b916e6e59dad5ec9ca55aa90afe8a90 (patch) | |
tree | 50850ae7a345afc1d75a9adb00e367d4528ef0e0 | |
parent | b33c333bcb88557ad23a9bc5be0d619d537984e9 (diff) | |
download | bubblewrap-b5f672355b916e6e59dad5ec9ca55aa90afe8a90.tar.gz |
Add --assert-userns-disabled option
We can't combine --disable-userns with entering an existing user
namespace via --userns if the existing user namespace was created with
--disable-userns, because its ability to create nested user namespaces
has already been disabled. However, the next best thing is to verify
that we are already in the desired state.
Signed-off-by: Simon McVittie <smcv@collabora.com>
-rw-r--r-- | bubblewrap.c | 24 | ||||
-rw-r--r-- | bwrap.xml | 11 | ||||
-rw-r--r-- | completions/bash/bwrap | 1 | ||||
-rw-r--r-- | completions/zsh/_bwrap | 1 | ||||
-rwxr-xr-x | tests/test-run.sh | 2 |
5 files changed, 30 insertions, 9 deletions
diff --git a/bubblewrap.c b/bubblewrap.c index bcfbe9d..be02004 100644 --- a/bubblewrap.c +++ b/bubblewrap.c @@ -73,6 +73,7 @@ static const char *opt_file_label = NULL; static bool opt_as_pid_1; const char *opt_chdir_path = NULL; +bool opt_assert_userns_disabled = FALSE; bool opt_disable_userns = FALSE; bool opt_unshare_user = FALSE; bool opt_unshare_user_try = FALSE; @@ -313,6 +314,7 @@ usage (int ecode, FILE *out) " --userns FD Use this user namespace (cannot combine with --unshare-user)\n" " --userns2 FD After setup switch to this user namespace, only useful with --userns\n" " --disable-userns Disable further use of user namespaces inside sandbox\n" + " --assert-userns-disabled Fail unless further use of user namespace inside sandbox is disabled\n" " --pidns FD Use this pid namespace (as parent namespace if using --unshare-pid)\n" " --uid UID Custom uid in the sandbox (requires --unshare-user or --userns)\n" " --gid GID Custom gid in the sandbox (requires --unshare-user or --userns)\n" @@ -1783,6 +1785,10 @@ parse_args_recurse (int *argcp, { opt_disable_userns = TRUE; } + else if (strcmp (arg, "--assert-userns-disabled") == 0) + { + opt_assert_userns_disabled = TRUE; + } else if (strcmp (arg, "--remount-ro") == 0) { if (argc < 2) @@ -3202,20 +3208,20 @@ main (int argc, /* We're in a new user namespace, we got back the bounding set, clear it again */ drop_cap_bounding_set (FALSE); - if (opt_disable_userns) - { - /* Verify that we can't make a new userns again */ - res = unshare (CLONE_NEWUSER); - - if (res == 0) - die ("unable to disable creation of new user namespaces"); - } - write_uid_gid_map (opt_sandbox_uid, ns_uid, opt_sandbox_gid, ns_gid, -1, FALSE, FALSE); } + if (opt_disable_userns || opt_assert_userns_disabled) + { + /* Verify that we can't make a new userns again */ + res = unshare (CLONE_NEWUSER); + + if (res == 0) + die ("creation of new user namespaces was not disabled as requested"); + } + /* All privileged ops are done now, so drop caps we don't need */ drop_privs (!is_privileged, TRUE); @@ -159,6 +159,17 @@ </para></listitem> </varlistentry> <varlistentry> + <term><option>--assert-userns-disabled</option></term> + <listitem><para> + Confirm that the process in the sandbox has been prevented from + creating further user namespaces, but without taking any particular + action to prevent that. For example, this can be combined with + <option>--userns</option> to check that the given user namespace + has already been set up to prevent the creation of further user + namespaces. + </para></listitem> + </varlistentry> + <varlistentry> <term><option>--pidns <arg choice="plain">FD</arg></option></term> <listitem><para>Use an existing pid namespace instead of creating one. This is often used with --userns, because the pid namespace must be owned by the same user namespace that bwrap uses. </para> <para>Note that this can be combined with --unshare-pid, and in that case it means that the sandbox will be in its own pid namespace, which is a child of the passed in one.</para></listitem> diff --git a/completions/bash/bwrap b/completions/bash/bwrap index 962d04c..ca18d89 100644 --- a/completions/bash/bwrap +++ b/completions/bash/bwrap @@ -10,6 +10,7 @@ _bwrap() { # Please keep sorted in LC_ALL=C order local boolean_options=" --as-pid-1 + --assert-userns-disabled --clearenv --disable-userns --help diff --git a/completions/zsh/_bwrap b/completions/zsh/_bwrap index 7488727..a2e2caf 100644 --- a/completions/zsh/_bwrap +++ b/completions/zsh/_bwrap @@ -27,6 +27,7 @@ _bwrap_args=( # Please sort alphabetically (in LC_ALL=C order) by option name '--add-seccomp-fd[Load and use seccomp rules from FD]: :_guard "[0-9]#" "file descriptor to read seccomp rules from"' + '--assert-userns-disabled[Fail unless further use of user namespace inside sandbox is disabled]' '--args[Parse NUL-separated args from FD]: :_guard "[0-9]#" "file descriptor with NUL-separated arguments"' '--as-pid-1[Do not install a reaper process with PID=1]' '--bind-try[Equal to --bind but ignores non-existent SRC]:source:_files:destination:_files' diff --git a/tests/test-run.sh b/tests/test-run.sh index f1506bb..585fbf4 100755 --- a/tests/test-run.sh +++ b/tests/test-run.sh @@ -126,10 +126,12 @@ else echo "ok - can pivot to new rootfs recursively" $BWRAP --dev-bind / / -- true + ! $BWRAP --assert-userns-disabled --dev-bind / / -- true $BWRAP --unshare-user --disable-userns --dev-bind / / -- true ! $BWRAP --unshare-user --disable-userns --dev-bind / / -- $BWRAP --dev-bind / / -- true $BWRAP --unshare-user --disable-userns --dev-bind / / -- sh -c "echo 2 > /proc/sys/user/max_user_namespaces || true; ! $BWRAP --dev-bind / / -- true" $BWRAP --unshare-user --disable-userns --dev-bind / / -- sh -c "echo 100 > /proc/sys/user/max_user_namespaces || true; ! $BWRAP --dev-bind / / -- true" + $BWRAP --unshare-user --disable-userns --dev-bind / / -- sh -c "! $BWRAP --dev-bind / / --assert-userns-disabled -- true" echo "ok - can disable nested userns" fi |