#!/bin/bash # Bubblewrap init example. # # This is a trusted definition, not a hard-coded policy type. It stages the # patched RMUX binary and a writable work directory outside the visible runtime # tree, enters a private mount namespace, hides the runtime control directory # (including the real listener/admin sockets), and finally execs RMUX with the # inherited listener descriptor. # # Path hiding is mount-namespace behavior, not a security boundary against # same-UID processes. See docs/contracts.md and PLAN.md. set -euo pipefail : "${KURUWA_LISTENER_FD:?KURUWA_LISTENER_FD missing}" : "${KURUWA_RMUX_BIN:?KURUWA_RMUX_BIN missing}" : "${KURUWA_INSTANCE_NAME:?KURUWA_INSTANCE_NAME missing}" : "${KURUWA_INSTANCE_DIR:?KURUWA_INSTANCE_DIR missing}" : "${KURUWA_INTERNAL_SOCKET:?KURUWA_INTERNAL_SOCKET missing}" BWRAP="${BWRAP:-$(command -v bwrap || true)}" if [[ -z "$BWRAP" || ! -x "$BWRAP" ]]; then echo "init-bwrap: bubblewrap not found (set BWRAP or put bwrap on PATH)" >&2 exit 1 fi INSTANCE_DIR="$KURUWA_INSTANCE_DIR" STAGE="$INSTANCE_DIR/bwrap-stage" WORK="$INSTANCE_DIR/work" mkdir -p "$STAGE" "$WORK" chmod 700 "$INSTANCE_DIR" "$STAGE" "$WORK" cp -- "$KURUWA_RMUX_BIN" "$STAGE/rmux" chmod 755 "$STAGE/rmux" RMUX_DAEMON="$(dirname "$KURUWA_RMUX_BIN")/rmux-daemon" if [[ -x "$RMUX_DAEMON" ]]; then cp -- "$RMUX_DAEMON" "$STAGE/rmux-daemon" chmod 755 "$STAGE/rmux-daemon" fi # runtime/instances/ -> runtime. Hide both the path the caller used and its # physical resolution, because /tmp in this workspace is an alias of a path # under the project. LEXICAL_RUNTIME_ROOT="$(dirname "$(dirname "$INSTANCE_DIR")")" PHYSICAL_RUNTIME_ROOT="$(cd "$LEXICAL_RUNTIME_ROOT" && pwd -P)" case "$LEXICAL_RUNTIME_ROOT" in "" | "/") echo "init-bwrap: refusing to hide an empty root or /" >&2 exit 1 ;; esac mounts=( --die-with-parent --ro-bind / / --bind "$WORK" /mnt --ro-bind "$STAGE" /opt --tmpfs /tmp --proc /proc --dev /dev ) # /tmp is hidden wholesale above; only add separate mounts for runtime roots # outside /tmp. A dedicated runtime path is still hidden even when it lives # outside /tmp. add_hide_path() { local path="$1" case "$path" in /tmp | /tmp/*) ;; *) mounts+=(--tmpfs "$path") ;; esac } add_hide_path "$LEXICAL_RUNTIME_ROOT" if [[ "$PHYSICAL_RUNTIME_ROOT" != "$LEXICAL_RUNTIME_ROOT" ]]; then add_hide_path "$PHYSICAL_RUNTIME_ROOT" fi exec "$BWRAP" "${mounts[@]}" \ --chdir /mnt \ --clearenv \ --setenv PATH /opt:/run/current-system/sw/bin:/usr/bin:/bin \ --setenv HOME /mnt \ --setenv TMPDIR /tmp \ --setenv SHELL /bin/sh \ --setenv TERM xterm-256color \ --setenv LANG C.UTF-8 \ --setenv KURUWA_LISTENER_FD "$KURUWA_LISTENER_FD" \ --setenv KURUWA_RMUX_BIN /opt/rmux \ --setenv KURUWA_INSTANCE_NAME "$KURUWA_INSTANCE_NAME" \ --setenv KURUWA_INSTANCE_DIR "$KURUWA_INSTANCE_DIR" \ --setenv KURUWA_INTERNAL_SOCKET "$KURUWA_INTERNAL_SOCKET" \ --setenv KURUWA_BWRAP 1 \ -- /opt/rmux --__internal-daemon "$KURUWA_INTERNAL_SOCKET" \ --listener-fd "$KURUWA_LISTENER_FD"