bubblewrap icon indicating copy to clipboard operation
bubblewrap copied to clipboard

Running bwrap as root with custom user namespace with more than 1 uid in uid_map fails

Open ygg-drop opened this issue 3 years ago • 1 comments

Hello,

for my use case I need to run bwrap as root user with a user namespace that has more than 1 uid in uid_map. I've tried to create a user namespace using unshare, configure uid_map using newuidmap and pass it to bwrap through --userns FD option. When I run bwrap this way though, it fails with the following error:

bwrap: Creating newroot failed: Value too large for data type

The below script (run as root) can be used to reproduce this issue. It works fine as a regular user.

#!/bin/sh

user="$(id -un)"
group="$(id -gn)"

# The problem manifests itself only when bwrap is run as root, so warn if script
# is not run as superuser.
if [ $(id -u) -ne 0 ]; then
  echo "WARNING: This script needs to be run as root to reproduce the problem with bwrap!"
fi

if ! grep -q "^${user}:" /etc/subuid || ! grep -q  "^${group}:" /etc/subgid; then
  echo "Missing $user entry in /etc/subuid or /etc/subgid!"
  echo "Run as root:"
  echo "grep -q '^${user}:' /etc/subuid || echo '${user}:200000:99999' >>/etc/subuid"
  echo "grep -q '^${group}:' /etc/subgid || echo '${group}:200000:99999' >>/etc/subgid"
  exit 2
fi

# Create a new user namespace in the background with a dummy process just to
# keep it alive.
unshare -U sh -c "sleep 30" &
child_pid=$!

# Set {uid,gid}_map in new user namespace to max allowed range.
# Need to have appropriate entries for user in /etc/subuid and /etc/subgid.
newuidmap $child_pid 0 $(grep "^${user}:" /etc/subuid | cut -d : -f 2- | tr : ' ')
newgidmap $child_pid 0 $(grep "^${group}:" /etc/subgid | cut -d : -f 2- | tr : ' ')

# Tell Bubblewrap to use our user namespace through fd 5.
bwrap \
  --ro-bind /bin /bin \
  --ro-bind /usr/bin /usr/bin \
  --ro-bind /lib /lib \
  --ro-bind /usr/lib /usr/lib \
  --unshare-ipc \
  --unshare-pid \
  --unshare-net \
  --unshare-uts \
  --unshare-cgroup \
  --userns 5 \
  --cap-add ALL \
  --uid 0 \
  --gid 0 \
  -- \
  sh -c 'id' \
  5< /proc/$child_pid/ns/user

# bwrap will error out with:
#  bwrap: Creating newroot failed: Value too large for data type

ygg-drop avatar Jun 27 '22 14:06 ygg-drop

bwrap: Creating newroot failed: Value too large for data type

This means mkdir() failed with EOVERFLOW, which is not documented in mkdir(2).

I would guess that it means the kernel thinks you are trying to create the directory with an owning uid or gid that doesn't exist in the namespace to which you are switching?

I don't know whether what you're aiming to do is possible. If you're running as root with full capabilities, then you can already do anything that the kernel will allow you to do, and you certainly don't need the setuid-root bwrap, newuidmap or newgidmap. You might have better success by writing C code that makes the syscalls you want to make, more directly.

smcv avatar Oct 25 '22 18:10 smcv