-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Open
Labels
Description
Component
chroot
Description
When only a user is provided for the userspec flag, set_context currently sets the gid to be uid:
Some(UserSpec::UserOnly(user)) => {
let uid = name_to_uid(user)?;
let gid = uid as libc::gid_t;
let strategy = Strategy::FromUID(uid, false);
set_supplemental_gids_with_strategy(strategy, options.groups.as_ref())?;
set_gid(gid).map_err(|e| ChrootError::SetGidFailed(user.to_string(), e))?;
set_uid(uid).map_err(|e| ChrootError::SetUserFailed(user.to_string(), e))?;
}The issue is that there is no guarantee that they are the same, such as the sync user by default in ubuntu has uid of 4 but gid of 65534 (nobody).
Test / Reproduction Steps
# GNU
chroot --userspec=sync /srv/chroot/uutils-test /bin/id
uid=4(sync) gid=65534(nogroup) groups=65534(nogroup)
# uutils
/usr/local/cargo/bin/coreutils chroot --userspec=sync /srv/chroot/uutils-test /bin/id
uid=4(sync) gid=4(adm) groups=4(adm),65534(nogroup)The user in chroot ends up with the adm group instead of nogroup.
STR:
#!/bin/bash
# docker run --privileged --rm -it -v `pwd`:/app rust bash /app/setup-chroot.sh
cd /app
cargo install --path . --locked --features unix
mkdir -p /srv/chroot/uutils-test/{bin,etc,lib,lib64,usr,dev,proc,sys,tmp}
chmod 1777 /srv/chroot/uutils-test/tmp
cp /etc/passwd /srv/chroot/uutils-test/etc/passwd
cp /etc/group /srv/chroot/uutils-test/etc/group
CHROOT=/srv/chroot/uutils-test
cp /usr/local/cargo/bin/coreutils "$CHROOT/bin/coreutils"
for u in [ arch b2sum b3sum base32 base64 basename basenc cat chgrp chmod chown chroot \
cksum comm cp csplit cut date dd df dir dircolors dirname du echo env expand \
expr factor false fmt fold groups hashsum head hostid hostname id install join \
kill link ln logname ls md5sum mkdir mkfifo mknod mktemp more mv nice nl \
nohup nproc numfmt od paste pathchk pinky pr printenv printf ptx pwd readlink \
realpath rm rmdir seq sha1sum sha224sum sha256sum sha3-224sum sha3-256sum sha3-384sum \
sha3-512sum sha384sum sha3sum sha512sum shake128sum shake256sum shred shuf \
sleep sort split stat stdbuf stty sum sync tac tail tee test timeout touch \
tr true truncate tsort tty uname unexpand uniq unlink uptime users vdir wc who \
whoami yes; do
ln -s coreutils "$CHROOT/bin/$u"
done
copy_binary() {
local src="$1" # path to binary on host
local dest="$2" # path inside chroot (e.g. /bin/bash)
# Copy the binary itself
mkdir -p "$CHROOT$(dirname "$dest")"
cp "$src" "$CHROOT$dest"
# Copy all absolute-path libraries (includes the loader)
ldd "$src" | grep -oE '/[^ ]+' | while read -r lib; do
[ -z "$lib" ] && continue
mkdir -p "$CHROOT$(dirname "$lib")"
cp "$lib" "$CHROOT$lib"
done
}
# 1. Copy the Rust coreutils binary and its libs
copy_binary /usr/local/cargo/bin/coreutils /bin/coreutils
# 2. Copy a shell (pick bash, dash, whatever you have)
copy_binary /bin/bash /bin/bash
mount --bind /dev "$CHROOT/dev"
mount --bind /proc "$CHROOT/proc"
mount --bind /sys "$CHROOT/sys"
chroot "$CHROOT" /bin/bash