Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: support recursive bwrap #172

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 34 additions & 8 deletions bubblewrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2316,6 +2316,40 @@ main (int argc,
if (umount2 ("oldroot", MNT_DETACH))
die_with_error ("unmount old root");

/* This is our second pivot. It's like we're a Silicon Valley startup flush
* with cash but short on ideas!
*
* We're aiming to make /newroot the real root, and get rid of /oldroot. To do
* that we need a temporary place to store it before we can unmount it.
*/
{ cleanup_free char *pivot_tmp = xstrdup ("bwrap-pivot-old-XXXXXX");
if (mount ("/newroot", "/newroot", NULL, MS_MGC_VAL | MS_BIND | MS_REC, NULL) < 0)
die_with_error ("setting up newroot bind");
if (chdir ("/newroot") != 0)
die_with_error ("chdir /newroot");
if (mkdtemp (pivot_tmp) == NULL)
{
/* If the user did a bind mount of /, try /tmp */
if (errno == EPERM || errno == EACCES)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you please also add EROFS here? I've seen this issue locally when '/' was mounted read only

{
free (pivot_tmp);
pivot_tmp = xstrdup ("tmp/bwrap-pivot-old-XXXXXX");
if (mkdtemp (pivot_tmp) == NULL)
die_with_error ("mkdtemp");
}
else
die_with_error ("mkdtemp");
}
if (pivot_root (".", pivot_tmp) != 0)
die_with_error ("pivot_root(/newroot)");
if (chroot (".") != 0)
die_with_error ("chroot .");
if (chdir ("/") != 0)
die_with_error ("chdir /");
if (umount2 (pivot_tmp, MNT_DETACH) < 0)
die_with_error ("unmount old root");
}

if (opt_unshare_user &&
(ns_uid != opt_sandbox_uid || ns_gid != opt_sandbox_gid) &&
opt_userns_block_fd == -1)
Expand All @@ -2332,14 +2366,6 @@ main (int argc,
-1, FALSE, FALSE);
}

/* Now make /newroot the real root */
if (chdir ("/newroot") != 0)
die_with_error ("chdir newroot");
if (chroot ("/newroot") != 0)
die_with_error ("chroot /newroot");
if (chdir ("/") != 0)
die_with_error ("chdir /");

/* All privileged ops are done now, so drop caps we don't need */
drop_privs (!is_privileged);

Expand Down
35 changes: 35 additions & 0 deletions tests/test-run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,23 @@ fi

echo "1..32"

have_userns=false
if ${BWRAP} --bind / / --unshare-user true 2>/dev/null; then
have_userns=true
fi

BIND_HOST_USR_ARGS="--ro-bind /usr /usr \
--ro-bind /var /var \
--ro-bind /tmp /tmp \
--ro-bind /sys /sys \
--proc /proc \
--dev /dev \
--symlink usr/lib /lib \
--symlink usr/lib64 /lib64 \
--symlink usr/bin /bin \
--symlink usr/sbin /sbin"
BWRAP_HOST="${BWRAP} ${BIND_HOST_USR_ARGS}"

# Test help
${BWRAP} --help > help.txt
assert_file_has_content help.txt "usage: ${BWRAP}"
Expand Down Expand Up @@ -141,6 +158,24 @@ else
echo "ok - we have the expected caps as uid 0"
fi

if ! $have_userns; then
if ! ${is_uidzero}; then
# We shouldn't be able to retain caps when setuid and running as non-root
if ${BWRAP_HOST} --unshare-all --cap-add ALL; then
assert_not_reached "--keep-caps worked when suid, bad!"
fi
fi
else
cat > recursive-bwrap.sh <<EOF
#!/usr/bin/sh
exec ${BWRAP_HOST} echo hello from a recursive namespace uid=\$(id -u)
EOF
chmod a+x recursive-bwrap.sh
${BWRAP_HOST} --unshare-all --cap-add ALL --uid 0 --gid 0 $(pwd)/recursive-bwrap.sh > out.txt
assert_file_has_content out.txt 'hello from a recursive namespace uid=0'
echo "ok keep caps"
fi

# Test --die-with-parent

cat >lockf-n.py <<EOF
Expand Down