480 lines
12 KiB
Bash
Executable file
480 lines
12 KiB
Bash
Executable file
#! /bin/sh
|
|
|
|
# $NetBSD: mksandbox,v 1.8 2015/07/05 11:47:14 jperkin Exp $
|
|
|
|
# Copyright (c) 2002,2012 Alistair Crooks <agc@NetBSD.org>
|
|
# All rights reserved.
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions
|
|
# are met:
|
|
# 1. Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# 2. Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
|
|
# Usage: mksandbox [--mounthost=host] [--rodirs=dir1,...] [--rwdirs=dir1,...]
|
|
# [--pkgsrc=dir] [--src=srcdir] [--xsrc=xsrcdir]
|
|
# [--without-pkgsrc] [--without-x] [--verbose] sandbox-dir
|
|
#
|
|
# A small shell script to set up a sandbox (usually for a pkgsrc bulk
|
|
# build), using null mounts.
|
|
|
|
pkgsrc=/usr/pkgsrc
|
|
src=/usr/src
|
|
xsrc=/usr/xsrc
|
|
rodirs=
|
|
rwdirs=
|
|
with_pkgsrc=yes
|
|
with_x=yes
|
|
|
|
kernel=""
|
|
sandboxWriteDirs=""
|
|
sandboxMountDirs="/bin /sbin /lib /libexec /usr/X11R7 /usr/bin /usr/games /usr/include /usr/lib /usr/libdata /usr/libexec /usr/lkm /usr/share /usr/sbin /var/mail"
|
|
sandboxEmptyDirs="/var/run /var/log /var/spool/lock /var/spool/mqueue"
|
|
sandboxEmptyFiles="/var/run/utmp /var/run/utmpx /var/log/wtmp /var/log/wtmpx /var/log/lastlog /var/log/lastlogx"
|
|
|
|
usage()
|
|
{
|
|
echo "usage: mksandbox [--mounthost=host] [--rodirs=dir1,...] [--rwdirs=dir1,...]"
|
|
echo " [--pkgsrc=dir] [--src=srcdir] [--xsrc=xsrcdir]"
|
|
echo " [--without-pkgsrc] [--without-x] [--verbose] sandbox-dir"
|
|
exit 1
|
|
}
|
|
|
|
err()
|
|
{
|
|
echo "error: $1"
|
|
exit 1
|
|
}
|
|
|
|
# by default, don't require src and xsrc to be available
|
|
need_src=no
|
|
need_xsrc=no
|
|
|
|
opsys=`uname -s`
|
|
case "$opsys" in
|
|
Darwin)
|
|
bmakeprog=bmake
|
|
chmodprog=/bin/chmod
|
|
chownprog=/usr/sbin/chown
|
|
cpprog=/bin/cp
|
|
gtarprog=/usr/bin/gnutar
|
|
idprog=/usr/bin/id
|
|
kernel=/mach_kernel
|
|
mkdirprog="/bin/mkdir -p"
|
|
mountflags="-t nfs"
|
|
mounthost="localhost"
|
|
mountprog=/sbin/mount
|
|
paxprog=/bin/pax
|
|
sedprog=/usr/bin/sed
|
|
sandboxEmptyDirs="$sandboxEmptyDirs /var/root"
|
|
sandboxMountDirs="$sandboxMountDirs /usr/llvm-gcc-4.2 /usr/X11 /System/Library /Library"
|
|
sandboxWriteDirs="$sandboxWriteDirs /Library/Server/Mail/Data"
|
|
;;
|
|
FreeBSD)
|
|
bmakeprog=bmake
|
|
chmodprog=/bin/chmod
|
|
chownprog=/usr/sbin/chown
|
|
cpprog=/bin/cp
|
|
gtarprog=/usr/bin/tar
|
|
idprog=/usr/bin/id
|
|
mkdirprog="/bin/mkdir -p"
|
|
mountflags="-t nullfs"
|
|
mountprog=/sbin/mount
|
|
paxprog=/bin/pax
|
|
sedprog=/usr/bin/sed
|
|
;;
|
|
Interix)
|
|
echo >&2 "This script cannot be used on Interix; a different procedure is required."
|
|
echo >&2 "(To be documented.)"
|
|
exit 1
|
|
;;
|
|
Linux)
|
|
bmakeprog=bmake
|
|
chmodprog=/bin/chmod
|
|
chownprog=/bin/chown
|
|
cpprog=/bin/cp
|
|
gtarprog=/bin/tar
|
|
idprog=/usr/bin/id
|
|
mkdirprog="/bin/mkdir -p"
|
|
mountflags="--bind"
|
|
if [ -f /bin/mount ]; then
|
|
mountprog=/bin/mount
|
|
else
|
|
mountprog=/sbin/mount
|
|
fi
|
|
paxprog=""
|
|
sedprog=/bin/sed
|
|
sandboxMountDirs="$sandboxMountDirs /lib64 /usr/lib64 /usr/kerberos /run"
|
|
sandboxWriteDirs="$sandboxWriteDirs /proc"
|
|
;;
|
|
NetBSD)
|
|
bmakeprog=make
|
|
chmodprog=/bin/chmod
|
|
chownprog=/usr/sbin/chown
|
|
cpprog=/bin/cp
|
|
gtarprog=/usr/bin/tar
|
|
idprog=/usr/bin/id
|
|
kernel=/netbsd
|
|
mkdirprog="/bin/mkdir -p"
|
|
mountflags="-t null"
|
|
mountprog=/sbin/mount
|
|
paxprog=/bin/pax
|
|
sedprog=/usr/bin/sed
|
|
need_src=yes
|
|
need_xsrc=yes
|
|
;;
|
|
SunOS)
|
|
bmakeprog=bmake
|
|
chmodprog=/usr/bin/chmod
|
|
chownprog=/usr/bin/chown
|
|
cpprog=/usr/bin/cp
|
|
gtarprog=""
|
|
idprog=/usr/xpg4/bin/id
|
|
mkdirprog="/usr/bin/mkdir -p"
|
|
mountflags="-F lofs"
|
|
mountprog=/sbin/mount
|
|
paxprog=/bin/pax
|
|
sedprog=/usr/xpg4/bin/sed
|
|
sandboxMountDirs="/bin /sbin /kernel /lib /proc /opt/SUNWspro /usr/X11R6 /usr/5bin /usr/bin /usr/ccs /usr/dt /usr/games /usr/include /usr/lib /usr/openwin /usr/share /usr/sbin /usr/sadm /usr/sfw /usr/ucb /usr/ucblib /usr/xpg4 /var/mail /var/sadm"
|
|
sandboxEmptyDirs="$sandboxEmptyDirs /usr/tmp /var/tmp"
|
|
;;
|
|
*)
|
|
echo "Unknown Operating System ($opsys) - good luck"
|
|
bmakeprog=bmake
|
|
chmodprog=chmod
|
|
chownprog=chown
|
|
cpprog=cp
|
|
gtarprog="tar"
|
|
idprog="id"
|
|
mkdirprog="mkdir -p"
|
|
mountflags="-t null"
|
|
mountprog=mount
|
|
paxprog=pax
|
|
sedprog=sed
|
|
;;
|
|
esac
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
--mounthost=*) mounthost=`echo $1 | $sedprog -e 's|^--mounthost=||'` ;;
|
|
--pkgsrc=*) pkgsrc=`echo $1 | $sedprog -e 's|^--pkgsrc=||'` ;;
|
|
--src=*) src=`echo $1 | $sedprog -e 's|^--src=||'` ;;
|
|
--xsrc=*) xsrc=`echo $1 | $sedprog -e 's|^--xsrc=||'` ;;
|
|
--rodirs=*) rodirs=`echo $1 | $sedprog -e 's|^--rodirs=||'` ;;
|
|
--rwdirs=*) rwdirs=`echo $1 | $sedprog -e 's|^--rwdirs=||'` ;;
|
|
--without-pkgsrc) with_pkgsrc=no ;;
|
|
--without-x) with_x=no ;;
|
|
--verbose) set -x ;;
|
|
-*) usage ;;
|
|
*) break ;;
|
|
esac
|
|
shift
|
|
done
|
|
|
|
if [ $# -ne 1 ]; then
|
|
usage
|
|
fi
|
|
|
|
if [ "$with_x" = "no" ]; then
|
|
need_xsrc=no
|
|
fi
|
|
|
|
if [ `$idprog -u` -ne 0 ]; then
|
|
err "You must be root to run this script."
|
|
fi
|
|
|
|
if [ -n "$mounthost" ]; then
|
|
mounthost="$mounthost:"
|
|
fi
|
|
|
|
if [ ! -d $pkgsrc -a "$with_pkgsrc" = "yes" ]; then
|
|
err "pkgsrc directory $pkgsrc does not exist."
|
|
fi
|
|
|
|
if [ ! -d $src -a "$need_src" = "yes" ]; then
|
|
err "source directory $src does not exist."
|
|
fi
|
|
|
|
if [ ! -d $xsrc -a "$need_xsrc" = "yes" ]; then
|
|
err "xsrc directory $xsrc does not exist."
|
|
fi
|
|
|
|
sandbox=$1
|
|
sandbox_script="$sandbox/sandbox"
|
|
|
|
if [ "$with_pkgsrc" = "yes" ]; then
|
|
packages=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=PACKAGES)`
|
|
distfiles=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=DISTDIR)`
|
|
localbase=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=LOCALBASE)`
|
|
pkg_dbdir=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=PKG_DBDIR)`
|
|
localpatches=`(cd $pkgsrc/pkgtools/lintpkgsrc; $bmakeprog show-var VARNAME=LOCALPATCHES)`
|
|
|
|
test -d "$localpatches" || echo "WARNING: LOCALPATCHES directory does not exist - ignoring"
|
|
fi
|
|
|
|
$mkdirprog $sandbox
|
|
cat > $sandbox_script <<EOS
|
|
#! /bin/sh -
|
|
mounthost=$mounthost
|
|
opsys=$opsys
|
|
sandbox=$sandbox
|
|
|
|
r3() {
|
|
_R=
|
|
while [ \$# -ge 3 ]
|
|
do
|
|
_R="\$1 \$2 \$3 \$_R"
|
|
shift; shift; shift
|
|
done
|
|
echo "\$_R"
|
|
}
|
|
|
|
fses="\\
|
|
EOS
|
|
|
|
if [ -n "$kernel" -a -f "$kernel" ]; then
|
|
echo "Copying the kernel"
|
|
$cpprog $kernel $sandbox
|
|
fi
|
|
|
|
if [ "$with_pkgsrc" = "yes" ]; then
|
|
echo "Checking package hierarchy in $localbase and package database in $pkg_dbdir exist"
|
|
$mkdirprog $sandbox/$localbase $sandbox/$pkg_dbdir
|
|
fi
|
|
|
|
echo "Make and populate $sandbox/dev"
|
|
$mkdirprog $sandbox/dev
|
|
|
|
case "$opsys" in
|
|
Darwin|FreeBSD)
|
|
$mountprog -t devfs devfs $sandbox/dev
|
|
;;
|
|
SunOS)
|
|
$mountprog -F lofs -r /dev $sandbox/dev
|
|
$mountprog -F fd fd $sandbox/dev/fd
|
|
;;
|
|
Linux)
|
|
$mountprog $mountflags /dev $sandbox/dev
|
|
;;
|
|
*)
|
|
$cpprog /dev/MAKEDEV* $sandbox/dev
|
|
(cd $sandbox/dev; ./MAKEDEV all)
|
|
esac
|
|
|
|
echo "Make and populate $sandbox/etc"
|
|
$mkdirprog $sandbox/etc
|
|
case "$paxprog" in
|
|
"") (cd /etc; $gtarprog -cf - . | (cd $sandbox/etc; $gtarprog xf - )) ;;
|
|
*) (cd /etc; $paxprog -rwpe . $sandbox/etc) ;;
|
|
esac
|
|
rm -f $sandbox/etc/localtime
|
|
|
|
case "$opsys" in
|
|
SunOS)
|
|
$cpprog /etc/TIMEZONE $sandbox/etc/TIMEZONE
|
|
;;
|
|
*)
|
|
$cpprog /usr/share/zoneinfo/GMT $sandbox/etc/localtime
|
|
;;
|
|
esac
|
|
|
|
echo "Make empty dirs upon which to mount the null mounts"
|
|
for d in $sandboxMountDirs; do
|
|
test -d $d || continue;
|
|
case $d in
|
|
*X11*) test "$with_x" = "yes" || continue ;;
|
|
esac
|
|
$mkdirprog $sandbox$d;
|
|
$mountprog $mountflags -r $mounthost$d $sandbox$d;
|
|
case "$opsys" in
|
|
Linux) $mountprog $mountflags -o remount,bind,ro $mounthost$d $sandbox$d ;;
|
|
esac
|
|
echo "$mounthost$d $d ro \\" >> $sandbox_script
|
|
done
|
|
for d in $sandboxWriteDirs; do
|
|
test -d $d || continue;
|
|
$mkdirprog $sandbox$d;
|
|
$mountprog $mountflags $mounthost$d $sandbox$d;
|
|
echo "$mounthost$d $d rw \\" >> $sandbox_script
|
|
done
|
|
|
|
echo "Making /tmp in $sandbox"
|
|
$mkdirprog $sandbox/tmp $sandbox/var/tmp
|
|
$chmodprog 1777 $sandbox/tmp $sandbox/var/tmp
|
|
|
|
$idprog games >/dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
echo "Making /var/games in $sandbox"
|
|
$mkdirprog $sandbox/var/games
|
|
$chownprog games:games $sandbox/var/games
|
|
$chmodprog 2775 $sandbox/var/games
|
|
fi
|
|
|
|
for d in $sandboxEmptyDirs; do
|
|
test -d $d || continue
|
|
echo "Making $d in $sandbox"
|
|
$mkdirprog $sandbox$d
|
|
done
|
|
|
|
for f in $sandboxEmptyFiles; do
|
|
test -f $f || continue
|
|
echo "Making $f in $sandbox"
|
|
$cpprog /dev/null $sandbox$f
|
|
done
|
|
|
|
if [ "$need_src" = "yes" ]; then
|
|
echo "Mount $src from $sandbox"
|
|
$mkdirprog $sandbox/usr/src
|
|
$mountprog $mountflags -r $mounthost$src $sandbox/usr/src
|
|
echo "$mounthost$src /usr/src ro \\" >> $sandbox_script
|
|
fi
|
|
|
|
if [ "$with_pkgsrc" = "yes" ]; then
|
|
echo "Mount $pkgsrc from $sandbox"
|
|
$mkdirprog $sandbox/usr/pkgsrc
|
|
$mountprog $mountflags $mounthost$pkgsrc $sandbox/usr/pkgsrc
|
|
echo "$mounthost$pkgsrc /usr/pkgsrc rw \\" >> $sandbox_script
|
|
|
|
echo "Mounting $packages and $distfiles from $sandbox"
|
|
$mkdirprog $sandbox/$packages $sandbox/$distfiles
|
|
$mkdirprog $packages $distfiles
|
|
$mountprog $mountflags $mounthost$packages $sandbox/$packages
|
|
$mountprog $mountflags $mounthost$distfiles $sandbox/$distfiles
|
|
echo "$mounthost$packages $packages rw \\" >> $sandbox_script
|
|
echo "$mounthost$distfiles $distfiles rw \\" >> $sandbox_script
|
|
|
|
if [ -n "$localpatches" ] && [ -d "$localpatches" ]; then
|
|
echo "Mounting $localpatches from $sandbox"
|
|
$mkdirprog $sandbox/$localpatches
|
|
$mountprog $mountflags $mounthost$localpatches $sandbox/$localpatches
|
|
echo "$mounthost$localpatches $localpatches rw \\" >> $sandbox_script
|
|
fi
|
|
fi
|
|
|
|
if [ "$need_xsrc" = "yes" ]; then
|
|
echo "Mount $xsrc from $sandbox"
|
|
$mkdirprog $sandbox/usr/xsrc
|
|
$mountprog $mountflags -r $mounthost$xsrc $sandbox/usr/xsrc
|
|
echo "$mounthost$xsrc /usr/xsrc ro \\" >> $sandbox_script
|
|
fi
|
|
|
|
if [ -n "$rodirs" ]; then
|
|
for dir in `echo $rodirs | $sedprog -e 's/,/ /g'`; do
|
|
echo "Mount $dir from $sandbox"
|
|
$mkdirprog $sandbox$dir
|
|
$mountprog $mountflags -r $mounthost$dir $sandbox$dir
|
|
case "$opsys" in
|
|
Linux) $mountprog $mountflags -o remount,bind,ro $mounthost$dir $sandbox$dir ;;
|
|
esac
|
|
echo "$mounthost$dir $dir ro \\" >> $sandbox_script
|
|
done
|
|
fi
|
|
|
|
if [ -n "$rwdirs" ]; then
|
|
for dir in `echo $rwdirs | $sedprog -e 's/,/ /g'`; do
|
|
echo "Mount $dir from $sandbox"
|
|
$mkdirprog $sandbox$dir
|
|
$mountprog $mountflags $mounthost$dir $sandbox$dir
|
|
echo "$mounthost$dir $dir rw \\" >> $sandbox_script
|
|
done
|
|
fi
|
|
|
|
cat >> $sandbox_script <<EOS
|
|
"
|
|
case x\$1 in
|
|
xmount)
|
|
set dummy \$fses
|
|
shift
|
|
while [ \$# -ge 3 ]; do
|
|
fs=\$1; shift
|
|
mntpoint=\$1; shift
|
|
rwro=\$1; shift
|
|
case \$rwro in
|
|
ro) $mountprog $mountflags -r \$fs \$sandbox/\$mntpoint || exit 1 ;;
|
|
rw) $mountprog $mountflags \$fs \$sandbox/\$mntpoint || exit 1 ;;
|
|
esac
|
|
done
|
|
case \$opsys in
|
|
Darwin|FreeBSD)
|
|
$mountprog -t devfs devfs \$sandbox/dev
|
|
;;
|
|
Linux)
|
|
$mountprog $mountflags /dev \$sandbox/dev
|
|
;;
|
|
SunOS)
|
|
$mountprog -F lofs -r /dev \$sandbox/dev
|
|
$mountprog -F fd fd \$sandbox/dev/fd
|
|
;;
|
|
esac
|
|
;;
|
|
xumount)
|
|
set dummy \`r3 \$fses\`
|
|
shift
|
|
while [ \$# -ge 3 ]; do
|
|
fs=\$1; shift
|
|
mntpoint=\$1; shift
|
|
dummy=\$1; shift
|
|
umount \$sandbox/\$mntpoint
|
|
done
|
|
case \$opsys in
|
|
Darwin|FreeBSD|Linux)
|
|
umount \$sandbox/dev
|
|
;;
|
|
SunOS)
|
|
umount \$sandbox/dev/fd
|
|
umount \$sandbox/dev
|
|
;;
|
|
esac
|
|
;;
|
|
xchroot)
|
|
case x\$2 in
|
|
x) rootshell=/bin/ksh ;;
|
|
*) rootshell="\$2" ;;
|
|
esac
|
|
script="\$sandbox/tmp/script.\$\$"
|
|
echo "#!/bin/sh" > \$script
|
|
echo "ENV=/etc/shrc \$rootshell" >> \$script
|
|
chmod +x \$script
|
|
ENV=/etc/shrc chroot \$sandbox /tmp/\`basename \$script\`
|
|
rm -f \$script
|
|
;;
|
|
*)
|
|
if [ \$# -eq 0 ]; then
|
|
set dummy /bin/sh
|
|
shift
|
|
fi
|
|
chroot \$sandbox "\$@"
|
|
;;
|
|
esac
|
|
EOS
|
|
|
|
chmod +x $sandbox_script
|
|
|
|
case $opsys in
|
|
Darwin)
|
|
$cpprog /var/run/resolv.conf $sandbox/var/run/resolv.conf
|
|
;;
|
|
SunOS)
|
|
$cpprog /etc/mnttab $sandbox/etc/mnttab
|
|
;;
|
|
*)
|
|
esac
|
|
|
|
echo "Sandbox creation is now complete"
|
|
|
|
exit 0
|