Prototype FreeBSD jail build isolation
This commit is contained in:
175
tests/daemon/run-freebsd-jail-build-prototype.sh
Executable file
175
tests/daemon/run-freebsd-jail-build-prototype.sh
Executable file
@@ -0,0 +1,175 @@
|
||||
#!/bin/sh
|
||||
set -eu
|
||||
|
||||
cc_bin=${CC_BIN:-/usr/bin/cc}
|
||||
cleanup_workdir=0
|
||||
jail_id=
|
||||
jail_name=
|
||||
mount_points=
|
||||
|
||||
if [ -n "${WORKDIR:-}" ]; then
|
||||
workdir=$WORKDIR
|
||||
mkdir -p "$workdir"
|
||||
else
|
||||
workdir=$(mktemp -d /tmp/fruix-jail-build-prototype.XXXXXX)
|
||||
cleanup_workdir=1
|
||||
fi
|
||||
|
||||
if [ "${KEEP_WORKDIR:-0}" -eq 1 ]; then
|
||||
cleanup_workdir=0
|
||||
fi
|
||||
|
||||
record_mount() {
|
||||
mount_points="$1
|
||||
$mount_points"
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
set +e
|
||||
if [ -n "$jail_id" ]; then
|
||||
sudo jail -r "$jail_id" >/dev/null 2>&1 || true
|
||||
fi
|
||||
|
||||
old_ifs=$IFS
|
||||
IFS='
|
||||
'
|
||||
for mount_point in $mount_points; do
|
||||
[ -n "$mount_point" ] || continue
|
||||
sudo umount "$mount_point" >/dev/null 2>&1 || true
|
||||
done
|
||||
IFS=$old_ifs
|
||||
|
||||
if [ "$cleanup_workdir" -eq 1 ]; then
|
||||
rm -rf "$workdir"
|
||||
fi
|
||||
}
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
root=$workdir/jail-root
|
||||
inputs=$workdir/inputs
|
||||
output=$workdir/output
|
||||
metadata_file=$workdir/jail-build-metadata.txt
|
||||
mounts_file=$workdir/jail-mounts.txt
|
||||
runtime_out=$workdir/runtime.out
|
||||
runtime_err=$workdir/runtime.err
|
||||
host_runtime_out=$workdir/host-runtime.out
|
||||
compile_log=$workdir/compile.log
|
||||
compile_err=$workdir/compile.err
|
||||
jls_out=$workdir/jls.txt
|
||||
outside_sentinel=$workdir/outside-sentinel
|
||||
|
||||
mkdir -p "$root/usr" "$root/tmp" "$inputs" "$output"
|
||||
chmod 1777 "$root/tmp"
|
||||
printf 'outside-visible-on-host-only\n' > "$outside_sentinel"
|
||||
|
||||
cat > "$inputs/hello.c" <<'EOF'
|
||||
#include <stdio.h>
|
||||
int main(void)
|
||||
{
|
||||
puts("hello-from-freebsd-jail-build");
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
readonly_mounts="/bin /lib /libexec /usr/bin /usr/include /usr/lib /usr/libdata /usr/libexec"
|
||||
for host_path in $readonly_mounts; do
|
||||
target=$root$host_path
|
||||
sudo mkdir -p "$target"
|
||||
sudo mount_nullfs -o ro "$host_path" "$target"
|
||||
record_mount "$target"
|
||||
done
|
||||
|
||||
for target in /inputs /output; do
|
||||
sudo mkdir -p "$root$target"
|
||||
done
|
||||
|
||||
sudo mount_nullfs -o ro "$inputs" "$root/inputs"
|
||||
record_mount "$root/inputs"
|
||||
sudo mount_nullfs "$output" "$root/output"
|
||||
record_mount "$root/output"
|
||||
|
||||
jail_name=fruix-jail-build-$$
|
||||
jail_id=$(sudo jail -i -c \
|
||||
name="$jail_name" \
|
||||
path="$root" \
|
||||
host.hostname="$jail_name" \
|
||||
persist \
|
||||
ip4=disable \
|
||||
ip6=disable)
|
||||
|
||||
sudo jls -n -j "$jail_id" > "$jls_out"
|
||||
mount | grep "$root" > "$mounts_file"
|
||||
|
||||
set +e
|
||||
sudo jexec "$jail_id" /bin/sh -eu -c '
|
||||
test ! -e /outside-sentinel
|
||||
/usr/bin/cc -Wall -Wextra /inputs/hello.c -o /output/hello
|
||||
' > "$compile_log" 2> "$compile_err"
|
||||
compile_rc=$?
|
||||
set -e
|
||||
|
||||
if [ "$compile_rc" -ne 0 ]; then
|
||||
echo "jail build prototype compile phase failed" >&2
|
||||
cat "$compile_log" >&2 || true
|
||||
cat "$compile_err" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
sudo jexec "$jail_id" /bin/sh -eu -c '/output/hello' > "$runtime_out" 2> "$runtime_err"
|
||||
runtime_rc=$?
|
||||
set -e
|
||||
|
||||
if [ "$runtime_rc" -ne 0 ]; then
|
||||
echo "jail build prototype runtime phase failed" >&2
|
||||
cat "$runtime_out" >&2 || true
|
||||
cat "$runtime_err" >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
|
||||
"$output/hello" > "$host_runtime_out"
|
||||
|
||||
cat > "$metadata_file" <<EOF
|
||||
workdir=$workdir
|
||||
jail_name=$jail_name
|
||||
jail_id=$jail_id
|
||||
jail_root=$root
|
||||
inputs_dir=$inputs
|
||||
output_dir=$output
|
||||
outside_sentinel=$outside_sentinel
|
||||
compile_log=$compile_log
|
||||
runtime_out=$runtime_out
|
||||
runtime_err=$runtime_err
|
||||
host_runtime_out=$host_runtime_out
|
||||
compile_err=$compile_err
|
||||
jls_out=$jls_out
|
||||
mounts_file=$mounts_file
|
||||
read_only_mounts=$readonly_mounts
|
||||
jail_compile_rc=$compile_rc
|
||||
jail_runtime_rc=$runtime_rc
|
||||
jail_runtime_output=$(tr '\n' '|' < "$runtime_out")
|
||||
host_runtime_output=$(tr '\n' '|' < "$host_runtime_out")
|
||||
outside_visibility_check=hidden-inside-jail
|
||||
EOF
|
||||
|
||||
if [ -n "${METADATA_OUT:-}" ]; then
|
||||
mkdir -p "$(dirname "$METADATA_OUT")"
|
||||
cp "$metadata_file" "$METADATA_OUT"
|
||||
fi
|
||||
|
||||
printf 'PASS freebsd-jail-build-prototype\n'
|
||||
printf 'Working directory: %s\n' "$workdir"
|
||||
printf 'Metadata file: %s\n' "$metadata_file"
|
||||
if [ -n "${METADATA_OUT:-}" ]; then
|
||||
printf 'Copied metadata to: %s\n' "$METADATA_OUT"
|
||||
fi
|
||||
printf '%s\n' '--- jail runtime output ---'
|
||||
cat "$runtime_out"
|
||||
printf '%s\n' '--- host runtime output ---'
|
||||
cat "$host_runtime_out"
|
||||
printf '%s\n' '--- jail parameters ---'
|
||||
cat "$jls_out"
|
||||
printf '%s\n' '--- nullfs mounts ---'
|
||||
cat "$mounts_file"
|
||||
printf '%s\n' '--- metadata ---'
|
||||
cat "$metadata_file"
|
||||
Reference in New Issue
Block a user