From 1f65e09865ead2f90178f0b04ed26dc1e9651d25 Mon Sep 17 00:00:00 2001 From: Gabriel Brown Date: Thu, 27 Aug 2026 10:44:14 -0400 Subject: [PATCH] Test: Prove verified bootstrap boundaries --- tests/setup/boot-contract | 20 ++++++ tests/setup/readme-contract | 83 ++++++++++++++++++++++ tests/setup/root-server-bootstrap-contract | 55 +++++++++++++- 3 files changed, 157 insertions(+), 1 deletion(-) diff --git a/tests/setup/boot-contract b/tests/setup/boot-contract index b8890cb..a79459c 100755 --- a/tests/setup/boot-contract +++ b/tests/setup/boot-contract @@ -64,8 +64,12 @@ case "\${1:-}" in [[ "\$#" -eq 5 && "\$5" == "$revision" ]] || exit 97 cp "$work/fake-install" "$clone_dir/install" chmod +x "$clone_dir/install" + printf '%s\n' '$revision' >"$clone_dir/.git/HEAD" elif [[ "\${4:-}" == -b ]]; then [[ "\$#" -eq 5 && "\$5" == main ]] || exit 97 + mkdir -p "$clone_dir/.git/refs/heads" + printf '%s\n' '$revision' >"$clone_dir/.git/refs/heads/main" + printf 'ref: refs/heads/main\n' >"$clone_dir/.git/HEAD" else exit 97 fi @@ -196,6 +200,22 @@ grep -qF "install PANAMA_PATH=$clone_dir" "$calls" \ grep -qE '^git (clone|.* pull)' "$calls" \ && note 'fresh bootstrap used mutable clone or pull behavior' +# A fresh fetch failure stops before any checked-out HEAD or executable +# handoff exists. The empty initialized Git directory is not a usable checkout. +configure_case fresh-fetch-failure +run_boot "$revision" "$boot_sha" +(( run_status != 0 )) || note 'fresh fetch failure returned success' +grep -qF "git -C $clone_dir fetch --depth=1 origin $revision" "$calls" \ + || note 'fresh fetch failure did not exercise the exact fetch' +assert_no_install_or_rewrite 'fresh fetch failure' +if grep -qE '^git .* (checkout|rev-parse)($| )' "$calls"; then + note 'fresh fetch failure reported or materialized a checked-out HEAD' +fi +if [[ -x "$clone_dir/install" || -e "$clone_dir/.git/HEAD" \ + || -e "$clone_dir/.git/refs/heads/main" ]]; then + note 'fresh fetch failure left a usable checkout' +fi + # A fetched checkout whose HEAD does not equal the requested commit never # creates the trusted branch or reaches install. configure_case head-mismatch "$mismatched_revision" diff --git a/tests/setup/readme-contract b/tests/setup/readme-contract index ed5643c..8d6ea20 100755 --- a/tests/setup/readme-contract +++ b/tests/setup/readme-contract @@ -19,6 +19,8 @@ panama="$repo_dir/bin/panama" findings=() note() { findings+=("$1"); } +work="$(mktemp -d)" +trap 'rm -rf -- "$work"' EXIT # ── Verified bootstrap command ─────────────────────────────────────────────── @@ -88,6 +90,87 @@ if grep -qE 'curl[^|]*\|[[:space:]]*(bash|sh)|bash[[:space:]]+<\(curl' "$readme" note 'the README pipes a network response into a shell' fi +# Run the two exact documented blocks with a successful download and a failing +# checksum. The Bash adapter records only the verified boot invocation; the +# contract itself uses /usr/bin/bash so the adapter cannot hide this behavior. +checksum_stub_dir="$work/checksum-bin" +checksum_boot_calls="$work/checksum-boot-calls" +mkdir -p "$checksum_stub_dir" + +cat >"$checksum_stub_dir/curl" <<'STUB' +#!/usr/bin/bash +set -u +destination="" +while (( $# > 0 )); do + case "$1" in + --output) + destination="${2:-}" + shift 2 + ;; + *) shift ;; + esac +done +[[ -n "$destination" ]] || exit 97 +printf 'tampered boot bytes\n' >"$destination" +STUB +chmod +x "$checksum_stub_dir/curl" + +cat >"$checksum_stub_dir/sha256sum" <<'STUB' +#!/usr/bin/bash +[[ "${1:-}" == -c ]] || exit 97 +exit 1 +STUB +chmod +x "$checksum_stub_dir/sha256sum" + +cat >"$checksum_stub_dir/bash" <<'STUB' +#!/usr/bin/bash +printf 'verified-boot %s\n' "$*" >>"$PANAMA_README_BOOT_CALLS" +exit 0 +STUB +chmod +x "$checksum_stub_dir/bash" + +mapfile -d $'\036' -t bootstrap_snippets < <( + awk ' + /^```sh$/ { in_block = 1; block = ""; next } + /^```$/ && in_block { + if (block ~ /bootstrap_commit=/) printf "%s%c", block, 30 + in_block = 0 + next + } + in_block { block = block $0 "\n" } + ' "$readme" +) + +checksum_failure_stops_boot() { + local snippet="$1" status + : >"$checksum_boot_calls" + PATH="$checksum_stub_dir:/usr/bin:/bin" \ + PANAMA_README_BOOT_CALLS="$checksum_boot_calls" \ + /usr/bin/bash -c "$snippet" >/dev/null 2>&1 + status=$? + (( status != 0 )) && [[ ! -s "$checksum_boot_calls" ]] +} + +if (( ${#bootstrap_snippets[@]} != 2 )); then + note 'the README does not contain exactly two executable verified bootstrap blocks' +else + bootstrap_labels=(desktop server) + for index in "${!bootstrap_snippets[@]}"; do + snippet="${bootstrap_snippets[$index]}" + label="${bootstrap_labels[$index]}" + if ! checksum_failure_stops_boot "$snippet"; then + note "the $label command invoked boot after checksum failure" + fi + + weakened_snippet="${snippet//$'set -euo pipefail\n'/}" + if [[ "$weakened_snippet" == "$snippet" ]]; then + note "the $label command has no fail-closed shell control to test" + elif checksum_failure_stops_boot "$weakened_snippet"; then + note "the $label checksum assertion accepts removal of fail-closed shell control" + fi + done +fi + # ── The contract count ─────────────────────────────────────────────────────── # # Counted the way `panama test` collects the suite, so the README agrees with diff --git a/tests/setup/root-server-bootstrap-contract b/tests/setup/root-server-bootstrap-contract index 790dc20..5b4fb03 100755 --- a/tests/setup/root-server-bootstrap-contract +++ b/tests/setup/root-server-bootstrap-contract @@ -127,6 +127,7 @@ esac write_executable(stub_dir / "runuser", common + r''' log runuser "$@" [[ "${1:-}" == -u && "${2:-}" == gib && "${3:-}" == -- ]] || exit 97 +target_user="$2" shift 3 if [[ "${1:-}" == install && "${2:-}" == -d && "${3:-}" == -m && "${4:-}" == 0700 && "${5:-}" == -- ]]; then /usr/bin/install "${@:2}" @@ -140,13 +141,17 @@ if [[ "${1:-}" == install && "${2:-}" == -m && "${3:-}" == 0600 && "${4:-}" == - >"$PANAMA_BOOT_FIXTURE_ROOT/state/target-key-meta" exit 0 fi -"$@" +PANAMA_BOOT_TARGET_USER="$target_user" "$@" ''') write_executable(stub_dir / "ssh-keygen", common + r''' log ssh-keygen "$@" exec /usr/bin/ssh-keygen "$@" ''') write_executable(stub_dir / "git", common + r''' +if [[ "${PANAMA_BOOT_TARGET_USER:-}" != gib ]]; then + log git-rejected-direct "$@" + exit 96 +fi log git "$@" case "${1:-}" in init) @@ -473,6 +478,7 @@ def configure_case( "signal-int-before-activation-cleanup-fails", "signal-int-during-candidate-preparation", "signal-term-during-backup-preparation", + "direct-root-git-probe", ): target_keys.write_text(TARGET_PUBLIC_KEY) elif name == "safe-root-key-copy": @@ -485,6 +491,29 @@ def configure_case( return fixture_root, stub_dir +def assert_checkout_runs_as_target(name: str, calls: str, fixture_root: Path) -> None: + call_lines = calls.splitlines() + git_indices = [ + index for index, line in enumerate(call_lines) if line.startswith("git ") + ] + if not git_indices: + return + + checkout = fixture_root / "home/gib/.local/share/Panama" + expected_mkdir = f"runuser -u gib -- mkdir -p {checkout.parent} " + if expected_mkdir not in call_lines: + note(f"{name}: checkout parent directory was not created as the target user") + + for index in git_indices: + expected_runuser = f"runuser -u gib -- {call_lines[index]}" + if index == 0 or call_lines[index - 1] != expected_runuser: + note(f"{name}: checkout Git operation bypassed the selected target user") + break + + if any(line.startswith("git-rejected-direct ") for line in call_lines): + note(f"{name}: checkout attempted a direct root Git operation") + + def run_case( name: str, *, @@ -614,6 +643,7 @@ fi note(f"{name}: bootstrap timed out, likely while reading an unsupported object") calls = (fixture_root / "calls").read_text() output = b"".join(chunks).decode(errors="replace") + assert_checkout_runs_as_target(name, calls, fixture_root) return status, output, calls, fixture_root, process.pid @@ -652,6 +682,29 @@ else: note("actual-root-fixture-guard: boot mutated its rejected fixture root") +probe_root, probe_stub_dir = configure_case("direct-root-git-probe") +probe_checkout = probe_root / "home/gib/.local/share/Panama" +probe_env = { + **os.environ, + "PATH": f"{probe_stub_dir}:/usr/bin:/bin", + "PANAMA_BOOT_FIXTURE_ROOT": str(probe_root), + "PANAMA_BOOT_REVISION": BOOT_REVISION, +} +direct_git = subprocess.run( + [str(probe_stub_dir / "git"), "init", str(probe_checkout)], + env=probe_env, + capture_output=True, + text=True, +) +probe_calls = (probe_root / "calls").read_text() +if direct_git.returncode != 96: + note("direct-root-git-probe: Git adapter accepted a root-owned checkout call") +if (probe_checkout / ".git").exists(): + note("direct-root-git-probe: rejected root-owned Git call mutated the checkout") +if "git-rejected-direct init " not in probe_calls: + note("direct-root-git-probe: fixture did not exercise the direct Git rejection") + + unsafe_cases = ( "missing", "empty",