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>
This commit is contained in:
Simon McVittie
2022-12-16 18:46:23 +00:00
committed by Alexander Larsson
parent b33c333bcb
commit b5f672355b
5 changed files with 30 additions and 9 deletions

View File

@@ -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);

View File

@@ -158,6 +158,17 @@
in the setuid version of bubblewrap.
</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>

View File

@@ -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

View File

@@ -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'

View File

@@ -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