Skip to content

Instantly share code, notes, and snippets.

@vjt
Created August 30, 2012 14:22
Show Gist options
  • Save vjt/3529509 to your computer and use it in GitHub Desktop.
Save vjt/3529509 to your computer and use it in GitHub Desktop.
#!/bin/bash
# Creates a chroot environment for the binaries
# passed on the command line, including the NSS
# subsystem, the RTLD and any dynamic libraries
# required by the binaries. Optionally, copies
# the given configuration files.
# Tested on Ubuntu 12.04 x86-64. Patches welcome.
# - vjt Thu Aug 30 16:24:02 CEST 2012
set -e
while true; do
case $1 in
-u) USER=$2;
shift 2 ;;
-c) CONFS="$CONFS $2"
shift 2 ;;
-h) help
exit -1 ;;
*) break ;;
esac
done
help() {
echo "Usage: $0 -u user [-c conf [-c conf] [...]] binary binary ..."
}
BINARIES=$*
ARCH=$(dpkg-architecture -qDEB_HOST_MULTIARCH)
echo "Creating directory tree..."
mkdir -p bin etc lib tmp
ln -sf lib lib64
echo "Copying NSS subsystem..."
ln -f /lib/$ARCH/libnss_{dns,compat,files}* lib/
ln -f /etc/{{host,nsswitch}.conf,hosts} etc/
# Handle symlinked resolv.conf
if [ -L /etc/resolv.conf ]; then
link=`readlink /etc/resolv.conf`
echo $link | grep -q ^/ && resolv=$link ||\
resolv=`dirname /etc/resolv.conf`/$link
cp $resolv etc/
else
ln -f /etc/resolv.conf etc/
fi
echo "Copying the RTLD..."
ld=/lib64/ld-linux-*.so.2
ln -f `readlink $ld` lib/`basename $ld`
echo "Creating passwd/group files..."
grep -E "root|$USER" /etc/passwd > etc/passwd
grep -E "root|`id -g $USER`" /etc/group > etc/group
if [ -n "$CONFS" ]; then
echo "Copying $CONFS"
cp $CONFS etc/
fi
for binary in $BINARIES; do
if [ ! -x $binary ]; then
echo "Non-executable binary $binary - skipping"
continue
fi
echo "Copying $binary and its libraries..."
ln -f $binary bin/
ldd $binary | awk '{print $3}' | grep ^/ | \
while read lib; do
ln -f $lib lib/
ln -f `dirname $lib`/`readlink $lib` lib/
done
done
bindfs() {
src=$1
dst=$2
echo "Bind-mounting $src into $dst"
mkdir -p $dst
if ! grep -q $dst /etc/fstab; then
cat >>/etc/fstab <<EOF
# Added by mkchroot on `date`
$src $dst none bind
EOF
fi
grep -q $dst /proc/mounts || mount $dst
}
root=`realpath .`
bindfs /run $root/var/run
bindfs /usr/share/zoneinfo $root/usr/share/zoneinfo
ln -f /etc/localtime etc/
echo "Done!"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment