#!/usr/bin/env bash set -Eeuo pipefail readonly ROOT="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/../.." && pwd -P)" readonly PROD="$ROOT/scripts/bootstrap/backup-slack-webhook-recovery.sh" readonly LIB="$ROOT/scripts/lib/slack-webhook-recovery.sh" fixture_dir='' runtime_fixture='' owned_work_fixture='' boundary_cases=0 review_failures=0 transaction_cases=0 production_runtime_root_definition='' fail() { printf 'TEST FAILURE: %s\n' "$*" >&2 exit 1 } assert_eq() { local expected="$1" actual="$2" description="$3" [[ "$actual" == "$expected" ]] || fail "$description" } assert_fails() { if "$@" >/dev/null 2>&1; then fail "expected failure: $*" fi } pass_boundary_case() { boundary_cases=$((boundary_cases + 1)) } pass_transaction_case() { transaction_cases=$((transaction_cases + 1)) } write_recovery_contract() { local destination="$1" builtin printf '%s\n' \ 'K3SLR_SCHEMA_VERSION=1' \ 'K3SLR_RECOVERY_DISK_BY_ID=/dev/disk/by-id/wwn-0x500a0751e6aa6254' \ 'K3SLR_RECOVERY_PARTITION_BY_ID=/dev/disk/by-id/wwn-0x500a0751e6aa6254-part3' \ 'K3SLR_RECOVERY_FS_UUID=4EA0196C0C5FA27E' \ 'K3SLR_RECOVERY_PARTUUID=4670aa9f-9045-4bce-930d-9e84dfec9f38' \ 'K3SLR_RECOVERY_MODEL=CT1000MX500SSD1' \ 'K3SLR_RECOVERY_SERIAL=2306E6AA6254' \ 'K3SLR_RECOVERY_WWN=0x500a0751e6aa6254' \ 'K3SLR_K3S_DISK_BY_ID=/dev/disk/by-id/wwn-0x500a07512df28bd1' \ 'K3SLR_K3S_PARTITION_BY_ID=/dev/disk/by-id/wwn-0x500a07512df28bd1-part1' \ 'K3SLR_K3S_FS_UUID=b86086ef-2b3c-4638-abcf-fc7f137dcb97' \ 'K3SLR_K3S_PARTUUID=b081b955-d6bc-442c-ac0f-db76560a5245' \ 'K3SLR_K3S_MODEL=CT250MX500SSD1' \ 'K3SLR_K3S_SERIAL=21132DF28BD1' \ 'K3SLR_K3S_WWN=0x500a07512df28bd1' \ 'K3SLR_OWNER_UID=1000' \ 'K3SLR_OWNER_GID=1000' \ 'K3SLR_OUTER_MOUNT=/mnt/k3s-recovery-ssd' \ 'K3SLR_INNER_MOUNT=/srv/recovery/k3s' \ 'K3SLR_ROOT_RELATIVE=HyeonworksRecovery' \ 'K3SLR_DATABASE_RELATIVE=HyeonworksRecovery/vault/hyeonworks-recovery.kdbx' \ 'K3SLR_CONTAINER_RELATIVE=HyeonworksRecovery/containers/k3s-recovery.luks' \ 'K3SLR_RUNTIME_METADATA_RELATIVE=HyeonworksRecovery/volume.env' \ 'K3SLR_MAPPING_NAME=k3s-recovery' \ 'K3SLR_PROOF_MAPPING_NAME=k3s-recovery-proof' \ 'K3SLR_INNER_LABEL=K3S_RECOVERY' \ 'K3SLR_CONTAINER_SIZE_BYTES=34359738368' \ 'K3SLR_MINIMUM_FREE_BYTES=10737418240' \ 'K3SLR_OUTER_MIN_REMAINING_PERCENT=20' >"$destination" chmod 0600 -- "$destination" } reset_fake_boundary() { : >"$fake_log" builtin printf '%s\n' absent >"$fake_mount_state" builtin printf '%s\n' 0 >"$fake_probe_status" builtin printf '%s\n' 0 >"$fake_mount_status" builtin printf '%s\n' 0 >"$fake_umount_status" builtin printf '%s\n' absent >"$fake_umount_after" builtin printf '%s\n' 0 >"$fake_sudo_status" builtin printf '%s\n' 0 >"$fake_source_query_count" builtin printf '%s\n' 0 >"$fake_action_count" builtin printf '%s\n' 0 >"$fake_mount_uncertain" builtin printf '%s\n' valid >"$fake_case_file" } fake_log_command() { local separator='' argument for argument in "$@"; do builtin printf '%s%s' "$separator" "$argument" >>"$fake_log" separator=$'\t' done builtin printf '\n' >>"$fake_log" } _swr_fake_runtime_root() { builtin printf '%s\n' "$fake_runtime_root" } _swr_fake_command() { fake_log_command "$@" local executable="$1" fake_case mount_state phase options shift if [[ "$executable" == /fixture/fake-only-sentinel ]]; then [[ $# -eq 0 ]] return fi fake_case="$(<"$fake_case_file")" case "$executable" in /usr/bin/readlink) [[ "$1" == -e && "$2" == -- && $# -eq 3 ]] || return 97 case "$3" in /run/user/1000) builtin printf '%s\n' /run/user/1000 ;; /dev/disk/by-id/wwn-0x500a0751e6aa6254) builtin printf '%s\n' /dev/fixture-recovery-disk ;; /dev/disk/by-id/wwn-0x500a0751e6aa6254-part3) builtin printf '%s\n' /dev/fixture-recovery-partition ;; /dev/disk/by-id/wwn-0x500a07512df28bd1) builtin printf '%s\n' /dev/fixture-k3s-disk ;; /dev/disk/by-id/wwn-0x500a07512df28bd1-part1) builtin printf '%s\n' /dev/fixture-k3s-partition ;; *) return 97 ;; esac ;; /usr/sbin/blkid) [[ "$1" == --output && "$2" == value && "$3" == --match-tag && "$5" == -- && $# -eq 6 ]] || return 97 case "$4|$6" in 'UUID|/dev/fixture-recovery-partition') [[ "$fake_case" == wrong_uuid ]] && builtin printf '%s\n' WRONG || builtin printf '%s\n' 4EA0196C0C5FA27E ;; 'PARTUUID|/dev/fixture-recovery-partition') builtin printf '%s\n' 4670aa9f-9045-4bce-930d-9e84dfec9f38 ;; 'TYPE|/dev/fixture-recovery-partition') [[ "$fake_case" == wrong_type ]] && builtin printf '%s\n' ext4 || builtin printf '%s\n' ntfs ;; *) return 97 ;; esac ;; /usr/bin/lsblk) [[ "$1" == --noheadings && "$2" == --raw && "$3" == --paths ]] || return 97 if [[ "$4" == --output && "$6" == -- && $# -eq 7 ]]; then case "$5|$7" in 'PKNAME|/dev/fixture-recovery-partition') [[ "$fake_case" == wrong_parent ]] && builtin printf '%s\n' /dev/fixture-other-disk || builtin printf '%s\n' /dev/fixture-recovery-disk ;; 'PKNAME|/dev/fixture-k3s-partition') [[ "$fake_case" == same_parent ]] && builtin printf '%s\n' /dev/fixture-recovery-disk || builtin printf '%s\n' /dev/fixture-k3s-disk ;; 'MODEL|/dev/fixture-recovery-disk') [[ "$fake_case" == wrong_model ]] && builtin printf '%s\n' WRONGMODEL '' || builtin printf '%s\n' CT1000MX500SSD1 '' ;; 'SERIAL|/dev/fixture-recovery-disk') builtin printf '%s\n' 2306E6AA6254 '' ;; 'WWN|/dev/fixture-recovery-disk') builtin printf '%s\n' 0x500a0751e6aa6254 '' ;; *) return 97 ;; esac elif [[ "$4" == --nodeps && "$5" == --output && "$7" == -- && $# -eq 8 ]]; then case "$6|$8" in 'MODEL|/dev/fixture-recovery-disk') [[ "$fake_case" == wrong_model ]] && builtin printf '%s\n' WRONGMODEL || builtin printf '%s\n' CT1000MX500SSD1 ;; 'SERIAL|/dev/fixture-recovery-disk') builtin printf '%s\n' 2306E6AA6254 ;; 'WWN|/dev/fixture-recovery-disk') builtin printf '%s\n' 0x500a0751e6aa6254 ;; *) return 97 ;; esac else return 97 fi ;; /usr/bin/findmnt) if [[ "$1" == --json && "$2" == --source && "$3" == /dev/fixture-recovery-partition && "$4" == --output && "$5" == SOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS && $# -eq 5 ]]; then local source_query_count source_query_count="$(( $(<"$fake_source_query_count") + 1 ))" builtin printf '%s\n' "$source_query_count" >"$fake_source_query_count" mount_state="$(<"$fake_mount_state")" [[ "$fake_case" == source_ambiguous ]] && return 2 if [[ "$fake_case" == source_rc1_nonempty || "$fake_case" == source_rc1_nonempty_poll1 && "$source_query_count" == 1 || "$fake_case" == source_rc1_nonempty_poll2 && "$source_query_count" == 2 ]]; then builtin printf '%s\n' '{"filesystems":[' return 1 fi if [[ "$fake_case" == source_rc1_overflow ]]; then local overflow builtin printf -v overflow '%*s' 16385 '' builtin printf '%s' "${overflow// /x}" return 1 fi case "$fake_case" in source_rc1_newline_1) builtin printf '\n'; return 1 ;; source_rc1_newline_2) builtin printf '\n\n'; return 1 ;; source_rc1_newline_overflow) local newline_overflow builtin printf -v newline_overflow '%*s' 16385 '' builtin printf '%s' "${newline_overflow// /$'\n'}" return 1 ;; esac [[ "$mount_state" == absent ]] && return 1 builtin printf '{"filesystems":[{"source":"/dev/fixture-recovery-partition","target":"%s","fstype":"fuseblk","vfs-options":"%s,nosuid,nodev,noexec","fs-options":"%s,allow_other,uid=1000,gid=1000,fmask=0177,dmask=0077"}]}\n' \ "$fake_mountpoint" "$mount_state" "$mount_state" return 0 fi if [[ "$1" == --json && "$2" == --mountpoint && "$3" == "$fake_runtime_root/slack-webhook-recovery."* && "$4" == --output && "$5" == SOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS && $# -eq 5 ]]; then fake_mountpoint="$3" mount_state="$(<"$fake_mount_state")" [[ "$fake_case" == target_reused && "$mount_state" == absent ]] && { builtin printf '{"filesystems":[{"source":"/dev/foreign","target":"%s","fstype":"ext4","vfs-options":"rw","fs-options":"rw"}]}\n' "$fake_mountpoint" return 0 } [[ "$mount_state" == absent ]] && return 1 local source=/dev/fixture-recovery-partition fstype=fuseblk local vfs_options="nodev,noexec,nosuid,relatime,${mount_state}" local fs_options="allow_other,blksize=4096,default_permissions,group_id=0,${mount_state},user_id=0" [[ "$fake_case" == foreign_source ]] && source=/dev/foreign [[ "$fake_case" == foreign_fstype ]] && fstype=ext4 [[ "$fake_case" == unsafe_allow_other ]] && fs_options="${mount_state},allow_other" [[ "$fake_case" == missing_nosuid ]] && vfs_options="nodev,noexec,relatime,${mount_state}" [[ "$fake_case" == vfs_relatime_missing ]] && vfs_options="nodev,noexec,nosuid,${mount_state}" [[ "$fake_case" == vfs_relatime_duplicate ]] && vfs_options+=",relatime" [[ "$fake_case" == vfs_phase_missing ]] && vfs_options="nodev,noexec,nosuid,relatime" [[ "$fake_case" == executable ]] && vfs_options="nodev,exec,nosuid,relatime,${mount_state}" [[ "$fake_case" == suid ]] && vfs_options="nodev,noexec,relatime,suid,${mount_state}" [[ "$fake_case" == dev ]] && vfs_options="dev,noexec,nosuid,relatime,${mount_state}" [[ "$fake_case" == wrong_phase ]] && vfs_options="nodev,noexec,nosuid,relatime,rw" [[ "$fake_case" == fs_allow_other_missing ]] && fs_options="${fs_options/allow_other,/}" [[ "$fake_case" == fs_allow_other_duplicate ]] && fs_options+=",allow_other" [[ "$fake_case" == fs_phase_missing ]] && fs_options="${fs_options/,${mount_state},/,}" [[ "$fake_case" == fs_wrong_phase ]] && fs_options="${fs_options/,${mount_state},/,rw,}" [[ "$fake_case" == legacy_explicit_mapping ]] && { vfs_options="${mount_state},nosuid,nodev,noexec" fs_options="${mount_state},allow_other,uid=1000,gid=1000,fmask=0177,dmask=0077" } [[ "$fake_case" == fs_default_permissions_missing ]] && fs_options="${fs_options/default_permissions,/}" [[ "$fake_case" == fs_default_permissions_duplicate ]] && fs_options+=",default_permissions" [[ "$fake_case" == fs_user_id_missing ]] && fs_options="${fs_options/,user_id=0/}" [[ "$fake_case" == fs_user_id_wrong ]] && fs_options="${fs_options/user_id=0/user_id=1000}" [[ "$fake_case" == fs_user_id_duplicate ]] && fs_options+=",user_id=0" [[ "$fake_case" == fs_group_id_missing ]] && fs_options="${fs_options/group_id=0,/}" [[ "$fake_case" == fs_group_id_wrong ]] && fs_options="${fs_options/group_id=0/group_id=1000}" [[ "$fake_case" == fs_group_id_duplicate ]] && fs_options+=",group_id=0" [[ "$fake_case" == fs_blksize_missing ]] && fs_options="${fs_options/blksize=4096,/}" [[ "$fake_case" == fs_blksize_wrong ]] && fs_options="${fs_options/blksize=4096/blksize=8192}" [[ "$fake_case" == fs_blksize_duplicate ]] && fs_options+=",blksize=4096" [[ "$fake_case" == field_placement_vfs_default_permissions ]] && vfs_options+=",default_permissions" [[ "$fake_case" == field_placement_fs_nodev ]] && fs_options+=",nodev" [[ "$fake_case" == hybrid_actual_legacy ]] && fs_options+=",uid=1000,gid=1000,fmask=0177,dmask=0077" [[ "$fake_case" == observed_permuted ]] && { vfs_options="${mount_state},relatime,nosuid,noexec,nodev" fs_options="${mount_state},user_id=0,group_id=0,default_permissions,blksize=4096,allow_other" } [[ "$fake_case" == json_fs_trailing_lf ]] && fs_options+=$'\n' [[ "$fake_case" == json_fs_trailing_lf_garbage ]] && fs_options+=$'\nunknown' [[ "$fake_case" == json_vfs_cross_field_reframe ]] && { vfs_options+=$'\n'"$fs_options" fs_options='' } [[ "$fake_case" == fs_uid_conflict ]] && fs_options+=",uid=0" [[ "$fake_case" == fs_uid_duplicate ]] && fs_options+=",uid=1000" [[ "$fake_case" == fs_gid_conflict ]] && fs_options+=",gid=0" [[ "$fake_case" == fs_gid_duplicate ]] && fs_options+=",gid=1000" [[ "$fake_case" == fs_fmask_conflict ]] && fs_options+=",fmask=0000" [[ "$fake_case" == fs_fmask_duplicate ]] && fs_options+=",fmask=0177" [[ "$fake_case" == fs_dmask_conflict ]] && fs_options+=",dmask=0000" [[ "$fake_case" == fs_dmask_duplicate ]] && fs_options+=",dmask=0077" [[ "$fake_case" == fs_umask ]] && fs_options+=",umask=0000" [[ "$fake_case" == fs_phase_conflict ]] && fs_options+=",rw" [[ "$fake_case" == fs_phase_duplicate ]] && fs_options+=",ro" [[ "$fake_case" == vfs_phase_duplicate ]] && vfs_options+=",ro" [[ "$fake_case" == vfs_nosuid_duplicate ]] && vfs_options+=",nosuid" [[ "$fake_case" == vfs_nodev_duplicate ]] && vfs_options+=",nodev" [[ "$fake_case" == vfs_noexec_duplicate ]] && vfs_options+=",noexec" [[ "$fake_case" == vfs_suid_conflict ]] && vfs_options+=",suid" [[ "$fake_case" == vfs_dev_conflict ]] && vfs_options+=",dev" [[ "$fake_case" == vfs_exec_conflict ]] && vfs_options+=",exec" case "$fake_case" in vfs_permissions) vfs_options+=",permissions" ;; vfs_acl) vfs_options+=",acl" ;; vfs_inherit) vfs_options+=",inherit" ;; vfs_unknown) vfs_options+=",unknown_fixture_token" ;; fs_permissions) fs_options+=",permissions" ;; fs_acl) fs_options+=",acl" ;; fs_inherit) fs_options+=",inherit" ;; fs_unknown) fs_options+=",unknown_fixture_token" ;; fs_arbitrary) fs_options+=",arbitrary_fixture_option" ;; vfs_empty) vfs_options='' ;; vfs_leading_comma) vfs_options=",${vfs_options}" ;; vfs_trailing_comma) vfs_options+="," ;; vfs_double_comma) vfs_options="${vfs_options/nosuid,/nosuid,,}" ;; fs_empty) fs_options='' ;; fs_leading_comma) fs_options=",${fs_options}" ;; fs_trailing_comma) fs_options+="," ;; fs_double_comma) fs_options="${fs_options/ro,/ro,,}" ;; esac builtin printf '{"filesystems":[{"source":"%s","target":"%s","fstype":"%s","vfs-options":"%s","fs-options":"%s"}]}\n' \ "$source" "$fake_mountpoint" "$fstype" "$vfs_options" "$fs_options" return 0 fi return 97 ;; /usr/bin/stat) if [[ "$1" == --format=%u:%g:%a && "$2" == -- && "$3" == /run/user/1000/platform-slack-keepass.* && $# -eq 3 ]]; then command /usr/bin/stat "$@" return fi if [[ "$1" == --file-system && "$2" == --format=%T && "$3" == -- && "$4" == /run/user/1000/platform-slack-keepass.* && $# -eq 4 ]]; then command /usr/bin/stat "$@" return fi [[ "$1" == --format=%u:%g:%a && "$2" == -- && "$3" == "$fake_runtime_root/slack-webhook-recovery."* && $# -eq 3 ]] || return 97 [[ "$fake_case" == wrong_owner ]] && builtin printf '%s\n' 1001:1000:700 && return 0 [[ "$fake_case" == wrong_gid ]] && builtin printf '%s\n' 1000:1001:700 && return 0 [[ "$fake_case" == wrong_mode ]] && builtin printf '%s\n' 1000:1000:755 && return 0 builtin printf '%s\n' 1000:1000:700 ;; /usr/bin/mktemp) [[ "$1" == -d && "$2" == -- && "$3" == "$fake_runtime_root/slack-webhook-recovery.XXXXXXXX" && $# -eq 3 ]] || return 97 command /usr/bin/mktemp "$@" ;; /usr/bin/chmod) command /usr/bin/chmod "$@" ;; /usr/bin/rmdir) command /usr/bin/rmdir "$@" ;; /usr/bin/jq) command /usr/bin/jq "$@" ;; /usr/bin/base64) command /usr/bin/base64 "$@" ;; /usr/bin/sudo) if [[ "$1" == -v && $# -eq 1 ]]; then return "$(<"$fake_sudo_status")" fi [[ "$1" == -n && "$2" == /usr/bin/timeout && "$3" == --signal=TERM ]] || return 97 if [[ "$4" == --kill-after=5s && "$5" == 20s && "$6" == /usr/bin/ntfs-3g.probe && "$7" == --readwrite && "$8" == /dev/fixture-recovery-partition && $# -eq 8 ]]; then return "$(<"$fake_probe_status")" fi if [[ "$4" == --kill-after=10s && "$5" == 45s && "$6" == /usr/bin/ntfs-3g && "$7" == -o && "$9" == /dev/fixture-recovery-partition && "${10}" == "$fake_runtime_root/slack-webhook-recovery."* && $# -eq 10 ]]; then fake_mountpoint="${10}" options="$8" case ",$options," in *,ro,*) phase=ro ;; *,rw,*) phase=rw ;; *) return 97 ;; esac if [[ "$(<"$fake_mount_status")" != 0 ]]; then [[ "$(<"$fake_mount_uncertain")" == 1 ]] && builtin printf '%s\n' "$phase" >"$fake_mount_state" return "$(<"$fake_mount_status")" fi builtin printf '%s\n' "$phase" >"$fake_mount_state" return 0 fi if [[ "$4" == --kill-after=10s && "$5" == 45s && "$6" == /usr/bin/umount && "$7" == -- && "$8" == "$fake_mountpoint" && $# -eq 8 ]]; then builtin printf '%s\n' "$(<"$fake_umount_after")" >"$fake_mount_state" return "$(<"$fake_umount_status")" fi return 97 ;; *) return 97 ;; esac } _swr_fake_volume_action() { local result_name="$1" phase="$2" builtin printf '%s\n' "$(( $(<"$fake_action_count") + 1 ))" >"$fake_action_count" case "$fake_action" in noop) builtin printf -v "$result_name" '%s' exact-noop ;; mutation) [[ "$phase" == ro ]] && builtin printf -v "$result_name" '%s' mutation || builtin printf -v "$result_name" '%s' complete ;; error) return 71 ;; signal) kill -TERM "$BASHPID" builtin printf -v "$result_name" '%s' exact-noop ;; *) return 97 ;; esac } assert_log_line() { local expected="$1" description="$2" /usr/bin/grep -Fqx -- "$expected" "$fake_log" || fail "$description" } test_contract_and_device_boundary() { local contract="$fixture_dir/local-recovery.env" variant="$fixture_dir/variant.env" local _swr_device='' _swr_no_nodeps='' identity_trace write_recovery_contract "$contract" _swr_load_recovery_contract "$contract" || fail 'strict synthetic recovery contract was rejected' assert_eq /dev/disk/by-id/wwn-0x500a0751e6aa6254 "$SWR_RECOVERY_DISK_BY_ID" 'recovery disk contract differs' assert_eq /dev/disk/by-id/wwn-0x500a0751e6aa6254-part3 "$SWR_RECOVERY_PARTITION_BY_ID" 'recovery partition contract differs' assert_eq 4EA0196C0C5FA27E "$SWR_RECOVERY_FS_UUID" 'recovery UUID contract differs' pass_boundary_case /usr/bin/awk 'NR != 3' "$contract" >"$variant" assert_fails _swr_load_recovery_contract "$variant" pass_boundary_case { command /usr/bin/cp -- "$contract" "$variant"; builtin printf '%s\n' 'K3SLR_SCHEMA_VERSION=1' >>"$variant"; } assert_fails _swr_load_recovery_contract "$variant" pass_boundary_case /usr/bin/awk 'NR == 2 { a=$0; next } NR == 3 { print; print a; next } { print }' "$contract" >"$variant" assert_fails _swr_load_recovery_contract "$variant" pass_boundary_case /usr/bin/sed '2s/^K3SLR_RECOVERY_DISK_BY_ID=/K3SLR_UNKNOWN=/' "$contract" >"$variant" assert_fails _swr_load_recovery_contract "$variant" pass_boundary_case /usr/bin/sed '2s/=/ /' "$contract" >"$variant" assert_fails _swr_load_recovery_contract "$variant" pass_boundary_case reset_fake_boundary assert_fails _swr_capture_single_line _swr_no_nodeps /usr/bin/lsblk \ --noheadings --raw --paths --output MODEL -- /dev/fixture-recovery-disk pass_boundary_case reset_fake_boundary _swr_load_recovery_contract "$contract" || fail 'valid contract reload failed' _swr_resolve_device _swr_device || fail 'exact synthetic device was rejected' assert_eq /dev/fixture-recovery-partition "$_swr_device" 'canonical recovery partition differs' assert_log_line $'/usr/sbin/blkid\t--output\tvalue\t--match-tag\tUUID\t--\t/dev/fixture-recovery-partition' 'fixed UUID probe argv differs' assert_log_line $'/usr/bin/lsblk\t--noheadings\t--raw\t--paths\t--output\tPKNAME\t--\t/dev/fixture-recovery-partition' 'fixed parent probe argv differs' identity_trace="$(/usr/bin/grep -E $'^/usr/bin/lsblk\t.*\t(MODEL|SERIAL|WWN)\t' "$fake_log")" assert_eq \ $'/usr/bin/lsblk\t--noheadings\t--raw\t--paths\t--nodeps\t--output\tMODEL\t--\t/dev/fixture-recovery-disk\n/usr/bin/lsblk\t--noheadings\t--raw\t--paths\t--nodeps\t--output\tSERIAL\t--\t/dev/fixture-recovery-disk\n/usr/bin/lsblk\t--noheadings\t--raw\t--paths\t--nodeps\t--output\tWWN\t--\t/dev/fixture-recovery-disk' \ "$identity_trace" 'fixed disk identity probe argv/order differs' pass_boundary_case local rejection for rejection in wrong_uuid wrong_type wrong_parent same_parent wrong_model; do reset_fake_boundary builtin printf '%s\n' "$rejection" >"$fake_case_file" assert_fails _swr_resolve_device _swr_device pass_boundary_case done reset_fake_boundary _swr_require_unmounted /dev/fixture-recovery-partition || fail 'stable absent source was rejected' pass_boundary_case builtin printf '%s\n' ro >"$fake_mount_state" assert_fails _swr_require_unmounted /dev/fixture-recovery-partition pass_boundary_case reset_fake_boundary builtin printf '%s\n' source_ambiguous >"$fake_case_file" assert_fails _swr_require_unmounted /dev/fixture-recovery-partition pass_boundary_case } test_probe_mount_and_validation_boundary() { local status first_stat_line findmnt_line last_stat_line _swr_created='' reset_fake_boundary _swr_probe_rw /dev/fixture-recovery-partition || fail 'successful read-write probe was rejected' assert_log_line $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=5s\t20s\t/usr/bin/ntfs-3g.probe\t--readwrite\t/dev/fixture-recovery-partition' 'fixed privileged probe argv differs' pass_boundary_case for status in 1 124 137 143 255; do reset_fake_boundary builtin printf '%s\n' "$status" >"$fake_probe_status" assert_fails _swr_probe_rw /dev/fixture-recovery-partition pass_boundary_case done reset_fake_boundary _swr_create_mountpoint _swr_created || fail 'private fixture mountpoint creation failed' fake_mountpoint="$_swr_created" [[ "$fake_mountpoint" == "$fake_runtime_root/slack-webhook-recovery."* ]] || fail 'mountpoint escaped private runtime root' [[ "$(/usr/bin/stat -c %a -- "$fake_mountpoint")" == 700 ]] || fail 'mountpoint mode differs' # Production break caught: installed ntfs-3g does not accept a standalone # `--` before DEVICE. The strict fake accepts only its documented argv. _swr_mount_volume /dev/fixture-recovery-partition "$fake_mountpoint" ro || fail 'closed read-only mount argv was rejected' assert_log_line $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/ntfs-3g\t-o\tnorecover,no_def_opts,allow_other,nodev,nosuid,noexec,uid=1000,gid=1000,fmask=0177,dmask=0077,ro\t/dev/fixture-recovery-partition\t'"$fake_mountpoint" 'fixed read-only mount argv differs' # Production break caught: removing the unsupported separator must not # allow an untrusted device or mountpoint to reach the privileged leaf. local adversarial_mountpoint : >"$fake_log" assert_fails _swr_mount_volume_command -o,allow_other "$fake_mountpoint" ro assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition -o,allow_other ro assert_fails _swr_mount_volume_command /tmp/arbitrary-device "$fake_mountpoint" ro assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition-sibling "$fake_mountpoint" ro assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition /tmp/arbitrary-mountpoint ro adversarial_mountpoint="$fake_runtime_root/slack-webhook-recovery.foreign" assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition "$adversarial_mountpoint" ro /usr/bin/ln -s -- "$fixture_dir" "$adversarial_mountpoint" assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition "$adversarial_mountpoint" ro /usr/bin/rm -f -- "$adversarial_mountpoint" builtin printf '%s\n' wrong_owner >"$fake_case_file" assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition "$fake_mountpoint" ro builtin printf '%s\n' wrong_mode >"$fake_case_file" assert_fails _swr_mount_volume_command /dev/fixture-recovery-partition "$fake_mountpoint" ro builtin printf '%s\n' valid >"$fake_case_file" ! /usr/bin/grep -Fq $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/ntfs-3g\t' "$fake_log" || fail 'untrusted mount operand reached the privileged command boundary' pass_boundary_case # Production break caught: findmnt reports the effective ntfs-3g FUSE # policy in normalized kernel-facing form rather than echoing uid/gid/masks. : >"$fake_log" builtin printf '%s\n' observed_normalized >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro || fail 'observed normalized read-only FUSE evidence was rejected' assert_eq 2 "$(/usr/bin/grep -Fc $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint" "$fake_log")" \ 'read-only mount validation did not couple option evidence to two private-root attestations' assert_log_line $'/usr/bin/findmnt\t--json\t--mountpoint\t'"$fake_mountpoint"$'\t--output\tSOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS' \ 'read-only mount validation findmnt argv differs' first_stat_line="$(/usr/bin/grep -nF $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint" "$fake_log" | /usr/bin/head -n 1)" findmnt_line="$(/usr/bin/grep -nF $'/usr/bin/findmnt\t--json\t--mountpoint\t'"$fake_mountpoint"$'\t--output\tSOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS' "$fake_log")" last_stat_line="$(/usr/bin/grep -nF $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint" "$fake_log" | /usr/bin/tail -n 1)" (( ${first_stat_line%%:*} < ${findmnt_line%%:*} && ${findmnt_line%%:*} < ${last_stat_line%%:*} )) || fail 'read-only option observation was not bracketed by private-root attestations' pass_boundary_case : >"$fake_log" builtin printf '%s\n' rw >"$fake_mount_state" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" rw || fail 'observed normalized writable FUSE evidence was rejected' assert_eq 2 "$(/usr/bin/grep -Fc $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint" "$fake_log")" \ 'writable mount validation did not couple option evidence to two private-root attestations' assert_log_line $'/usr/bin/findmnt\t--json\t--mountpoint\t'"$fake_mountpoint"$'\t--output\tSOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS' \ 'writable mount validation findmnt argv differs' first_stat_line="$(/usr/bin/grep -nF $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint" "$fake_log" | /usr/bin/head -n 1)" findmnt_line="$(/usr/bin/grep -nF $'/usr/bin/findmnt\t--json\t--mountpoint\t'"$fake_mountpoint"$'\t--output\tSOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS' "$fake_log")" last_stat_line="$(/usr/bin/grep -nF $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint" "$fake_log" | /usr/bin/tail -n 1)" (( ${first_stat_line%%:*} < ${findmnt_line%%:*} && ${findmnt_line%%:*} < ${last_stat_line%%:*} )) || fail 'writable option observation was not bracketed by private-root attestations' pass_boundary_case builtin printf '%s\n' observed_permuted >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" rw || fail 'permuted normalized writable FUSE evidence was rejected' pass_boundary_case builtin printf '%s\n' ro >"$fake_mount_state" local rejection for rejection in \ foreign_source foreign_fstype wrong_owner wrong_gid wrong_mode unsafe_allow_other \ missing_nosuid vfs_relatime_missing vfs_relatime_duplicate vfs_phase_missing \ executable suid dev wrong_phase legacy_explicit_mapping \ fs_allow_other_missing fs_allow_other_duplicate fs_phase_missing fs_wrong_phase \ fs_default_permissions_missing fs_default_permissions_duplicate \ fs_user_id_missing fs_user_id_wrong fs_user_id_duplicate \ fs_group_id_missing fs_group_id_wrong fs_group_id_duplicate \ fs_blksize_missing fs_blksize_wrong fs_blksize_duplicate \ field_placement_vfs_default_permissions field_placement_fs_nodev hybrid_actual_legacy \ fs_uid_conflict fs_uid_duplicate fs_gid_conflict fs_gid_duplicate \ fs_fmask_conflict fs_fmask_duplicate fs_dmask_conflict fs_dmask_duplicate \ fs_permissions fs_acl fs_inherit fs_arbitrary; do builtin printf '%s\n' "$rejection" >"$fake_case_file" assert_fails _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro pass_boundary_case done builtin printf '%s\n' valid >"$fake_case_file" builtin printf '%s\n' absent >"$fake_mount_state" builtin printf '%s\n' target_reused >"$fake_case_file" assert_fails _swr_require_mountpoint_unused "$fake_mountpoint" pass_boundary_case builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" } test_unmount_and_cycle_boundary() { local status mode second_probe_line mount_line post_probe_trace probes mounts _swr_created='' for status in 0 32 124 143 255; do reset_fake_boundary builtin printf '%s\n' ro >"$fake_mount_state" builtin printf '%s\n' "$status" >"$fake_umount_status" _swr_unmount_volume /dev/fixture-recovery-partition "$fake_mountpoint" || fail "stable absence after unmount status $status was rejected" assert_log_line $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/umount\t--\t'"$fake_mountpoint" 'fixed privileged unmount argv differs' pass_boundary_case done reset_fake_boundary builtin printf '%s\n' ro >"$fake_mount_state" builtin printf '%s\n' ro >"$fake_umount_after" assert_fails _swr_unmount_volume /dev/fixture-recovery-partition "$fake_mountpoint" [[ "$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/umount\t--\t'"$fake_mountpoint" "$fake_log")" == 1 ]] || fail 'unmount retried a retained source' ! /usr/bin/grep -Eq $'\t(-l|-f|--lazy|--force)(\t|$)' "$fake_log" || fail 'lazy or force unmount was attempted' pass_boundary_case reset_fake_boundary builtin printf '%s\n' ro >"$fake_mount_state" builtin printf '%s\n' source_ambiguous >"$fake_case_file" assert_fails _swr_unmount_volume /dev/fixture-recovery-partition "$fake_mountpoint" pass_boundary_case for mode in noop mutation error signal; do reset_fake_boundary fake_action="$mode" _swr_create_mountpoint _swr_created || fail 'cycle mountpoint creation failed' fake_mountpoint="$_swr_created" if [[ "$mode" == noop || "$mode" == mutation ]]; then _swr_run_volume_cycle /dev/fixture-recovery-partition "$fake_mountpoint" || fail "$mode cycle failed" else assert_fails _swr_run_volume_cycle /dev/fixture-recovery-partition "$fake_mountpoint" fi assert_eq absent "$(<"$fake_mount_state")" "$mode cycle did not unmount" probes="$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=5s\t20s\t/usr/bin/ntfs-3g.probe' "$fake_log")" mounts="$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/ntfs-3g\t-o' "$fake_log")" if [[ "$mode" == mutation ]]; then assert_eq 2 "$probes" 'mutation cycle probe count differs' assert_eq 2 "$mounts" 'mutation cycle mount count differs' second_probe_line="$(/usr/bin/grep -nF $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=5s\t20s\t/usr/bin/ntfs-3g.probe\t--readwrite\t/dev/fixture-recovery-partition' "$fake_log" | /usr/bin/tail -n 1)" mount_line="$(/usr/bin/grep -nF $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/ntfs-3g\t-o\tnorecover,no_def_opts,allow_other,nodev,nosuid,noexec,uid=1000,gid=1000,fmask=0177,dmask=0077,rw\t/dev/fixture-recovery-partition\t'"$fake_mountpoint" "$fake_log" | /usr/bin/tail -n 1)" post_probe_trace="$(/usr/bin/sed -n "$(( ${second_probe_line%%:*} + 1 )),$(( ${mount_line%%:*} ))p" "$fake_log")" assert_eq \ $'/usr/bin/stat\t--format=%u:%g:%a\t--\t'"$fake_mountpoint"$'\n/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/ntfs-3g\t-o\tnorecover,no_def_opts,allow_other,nodev,nosuid,noexec,uid=1000,gid=1000,fmask=0177,dmask=0077,rw\t/dev/fixture-recovery-partition\t'"$fake_mountpoint" \ "$post_probe_trace" 'fresh mountpoint attestation was not immediately between second probe and writable mount' else assert_eq 1 "$probes" "$mode cycle probe count differs" assert_eq 1 "$mounts" "$mode cycle mount count differs" fi command /usr/bin/rmdir -- "$fake_mountpoint" pass_boundary_case done } test_full_fake_boundary_ordering() { local contract="$fixture_dir/local-recovery.env" first_sudo last_preflight _swr_result='' reset_fake_boundary fake_action=noop write_recovery_contract "$contract" _swr_open_recovery_boundary _swr_result "$contract" || fail 'full fake recovery boundary failed' assert_eq exact-noop "$_swr_result" 'full fake no-op result differs' first_sudo="$(/usr/bin/grep -n '^/usr/bin/sudo' "$fake_log" | /usr/bin/head -n 1)" last_preflight="$(/usr/bin/grep -n $'^/usr/bin/findmnt\t--json\t--source' "$fake_log" | /usr/bin/head -n 1)" (( ${first_sudo%%:*} > ${last_preflight%%:*} )) || fail 'sudo validation ran before user-space preflight completed' assert_log_line $'/usr/bin/sudo\t-v' 'fixed sudo validation argv differs' [[ ! -e "$fake_mountpoint" ]] || fail 'full boundary left its mountpoint behind' pass_boundary_case } review_findmnt_initial_rc1_nonempty() { reset_fake_boundary builtin printf '%s\n' source_rc1_nonempty >"$fake_case_file" _swr_require_unmounted /dev/fixture-recovery-partition && fail 'findmnt RC1 nonempty initial output was accepted as absence' return 0 } review_findmnt_post_poll1_rc1_nonempty() { reset_fake_boundary builtin printf '%s\n' ro >"$fake_mount_state" builtin printf '%s\n' source_rc1_nonempty_poll1 >"$fake_case_file" _swr_unmount_volume /dev/fixture-recovery-partition "$fake_mountpoint" >/dev/null 2>&1 && fail 'findmnt RC1 nonempty first cleanup poll was accepted as absence' return 0 } review_findmnt_post_poll2_rc1_nonempty() { reset_fake_boundary builtin printf '%s\n' ro >"$fake_mount_state" builtin printf '%s\n' source_rc1_nonempty_poll2 >"$fake_case_file" _swr_unmount_volume /dev/fixture-recovery-partition "$fake_mountpoint" >/dev/null 2>&1 && fail 'findmnt RC1 nonempty second cleanup poll was accepted as absence' return 0 } review_findmnt_rc1_overflow() { reset_fake_boundary builtin printf '%s\n' source_rc1_overflow >"$fake_case_file" _swr_require_unmounted /dev/fixture-recovery-partition && fail 'findmnt RC1 overflowing output was accepted as absence' return 0 } review_sudo_after_complete_preflight() { local contract="$fixture_dir/local-recovery.env" _swr_result='' local sudo_line mktemp_line chmod_line stat_line unused_line probe_line local post_sudo_trace reset_fake_boundary fake_action=noop write_recovery_contract "$contract" _swr_open_recovery_boundary _swr_result "$contract" || fail 'ordered fake boundary unexpectedly failed' sudo_line="$(/usr/bin/grep -n $'^/usr/bin/sudo\t-v$' "$fake_log" | /usr/bin/head -n 1)" mktemp_line="$(/usr/bin/grep -n $'^/usr/bin/mktemp\t-d\t--' "$fake_log" | /usr/bin/head -n 1)" chmod_line="$(/usr/bin/grep -n $'^/usr/bin/chmod\t0700\t--' "$fake_log" | /usr/bin/head -n 1)" stat_line="$(/usr/bin/grep -n $'^/usr/bin/stat\t--format=%u:%g:%a\t--' "$fake_log" | /usr/bin/head -n 1)" unused_line="$(/usr/bin/grep -n $'^/usr/bin/findmnt\t--json\t--mountpoint' "$fake_log" | /usr/bin/head -n 1)" [[ -n "$sudo_line" && -n "$mktemp_line" && -n "$chmod_line" && -n "$stat_line" && -n "$unused_line" ]] || fail 'complete mountpoint preflight trace was absent' (( ${mktemp_line%%:*} < ${sudo_line%%:*} && ${chmod_line%%:*} < ${sudo_line%%:*} && ${stat_line%%:*} < ${sudo_line%%:*} && ${unused_line%%:*} < ${sudo_line%%:*} )) || fail 'sudo refresh preceded complete mountpoint preflight' probe_line="$(/usr/bin/grep -n $'^/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=5s' "$fake_log" | /usr/bin/head -n 1)" post_sudo_trace="$(/usr/bin/sed -n "$(( ${sudo_line%%:*} + 1 )),$(( ${probe_line%%:*} - 1 ))p" "$fake_log")" [[ "$post_sudo_trace" == *$'/usr/bin/stat\t--format=%u:%g:%a\t--'* && "$post_sudo_trace" == *$'/usr/bin/findmnt\t--json\t--mountpoint'* ]] || fail 'post-sudo defensive mountpoint recheck was absent' } review_sudo_failure_cleans_owned_mountpoint() { local contract="$fixture_dir/local-recovery.env" _swr_result='' cleaned_mountpoint reset_fake_boundary fake_action=noop write_recovery_contract "$contract" builtin printf '%s\n' 1 >"$fake_sudo_status" _swr_open_recovery_boundary _swr_result "$contract" >/dev/null 2>&1 && fail 'sudo refresh failure was accepted' cleaned_mountpoint="$(/usr/bin/grep $'^/usr/bin/chmod\t0700\t--\t' "$fake_log" | /usr/bin/cut -f4 | /usr/bin/head -n 1)" [[ "$(/usr/bin/grep -Fc $'/usr/bin/mktemp\t-d\t--' "$fake_log")" == 1 && "$(/usr/bin/grep -Fc $'/usr/bin/rmdir\t--' "$fake_log")" == 1 && "$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t' "$fake_log")" == 0 && -n "$cleaned_mountpoint" && ! -e "$cleaned_mountpoint" ]] || fail 'sudo failure did not clean only its owned unused mountpoint' } review_preflight_failure_has_no_privileged_call() { local contract="$fixture_dir/local-recovery.env" _swr_result='' reset_fake_boundary fake_action=noop write_recovery_contract "$contract" builtin printf '%s\n' target_reused >"$fake_case_file" _swr_open_recovery_boundary _swr_result "$contract" >/dev/null 2>&1 && fail 'reused mountpoint preflight was accepted' ! /usr/bin/grep -q '^/usr/bin/sudo' "$fake_log" || fail 'privileged call occurred before reused-mountpoint rejection' } review_mount_option_conflicts() { local rejection _swr_created='' local -a rejections=( legacy_explicit_mapping vfs_relatime_missing vfs_relatime_duplicate vfs_phase_missing fs_allow_other_missing fs_allow_other_duplicate fs_phase_missing fs_wrong_phase fs_default_permissions_missing fs_default_permissions_duplicate fs_user_id_missing fs_user_id_wrong fs_user_id_duplicate fs_group_id_missing fs_group_id_wrong fs_group_id_duplicate fs_blksize_missing fs_blksize_wrong fs_blksize_duplicate field_placement_vfs_default_permissions field_placement_fs_nodev hybrid_actual_legacy fs_uid_conflict fs_uid_duplicate fs_gid_conflict fs_gid_duplicate fs_fmask_conflict fs_fmask_duplicate fs_dmask_conflict fs_dmask_duplicate fs_umask fs_phase_conflict fs_phase_duplicate vfs_phase_duplicate vfs_nosuid_duplicate vfs_nodev_duplicate vfs_noexec_duplicate vfs_suid_conflict vfs_dev_conflict vfs_exec_conflict ) reset_fake_boundary _swr_create_mountpoint _swr_created || fail 'option-conflict mountpoint creation failed' fake_mountpoint="$_swr_created" builtin printf '%s\n' ro >"$fake_mount_state" for rejection in "${rejections[@]}"; do builtin printf '%s\n' "$rejection" >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro >/dev/null 2>&1 && fail "mount option conflict was accepted: $rejection" done builtin printf '%s\n' observed_normalized >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro || fail 'observed normalized mount options were rejected' builtin printf '%s\n' observed_permuted >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro || fail 'permuted normalized mount options were rejected' builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" } review_normalized_mount_option_grammar_both_phases() { local phase opposite vfs fs candidate local -a invalid_vfs=() invalid_fs=() for phase in ro rw; do [[ "$phase" == ro ]] && opposite=rw || opposite=ro vfs="nodev,noexec,nosuid,relatime,${phase}" fs="allow_other,blksize=4096,default_permissions,group_id=0,${phase},user_id=0" _swr_mount_options_are_safe "$phase" "$vfs" "$fs" || fail "normalized $phase mount option set was rejected" _swr_mount_options_are_safe "$phase" \ "${phase},relatime,nosuid,noexec,nodev" \ "${phase},user_id=0,group_id=0,default_permissions,blksize=4096,allow_other" || fail "permuted normalized $phase mount option set was rejected" invalid_vfs=( "nodev,noexec,nosuid,${phase}" "nodev,noexec,nosuid,relatime,relatime,${phase}" 'nodev,noexec,nosuid,relatime' "nodev,noexec,nosuid,relatime,${opposite}" "nodev,noexec,nosuid,relatime,${phase},${phase}" "nodev,noexec,nosuid,relatime,${phase},default_permissions" ) for candidate in "${invalid_vfs[@]}"; do assert_fails _swr_mount_options_are_safe "$phase" "$candidate" "$fs" done invalid_fs=( "blksize=4096,default_permissions,group_id=0,${phase},user_id=0" "allow_other,allow_other,blksize=4096,default_permissions,group_id=0,${phase},user_id=0" 'allow_other,blksize=4096,default_permissions,group_id=0,user_id=0' "allow_other,blksize=4096,default_permissions,group_id=0,${opposite},user_id=0" "allow_other,blksize=4096,default_permissions,group_id=0,${phase},${phase},user_id=0" "allow_other,blksize=4096,group_id=0,${phase},user_id=0" "allow_other,blksize=4096,default_permissions,default_permissions,group_id=0,${phase},user_id=0" "allow_other,blksize=4096,default_permissions,group_id=0,${phase}" "allow_other,blksize=4096,default_permissions,group_id=0,${phase},user_id=1000" "allow_other,blksize=4096,default_permissions,group_id=0,${phase},user_id=0,user_id=0" "allow_other,blksize=4096,default_permissions,${phase},user_id=0" "allow_other,blksize=4096,default_permissions,group_id=1000,${phase},user_id=0" "allow_other,blksize=4096,default_permissions,group_id=0,group_id=0,${phase},user_id=0" "allow_other,default_permissions,group_id=0,${phase},user_id=0" "allow_other,blksize=8192,default_permissions,group_id=0,${phase},user_id=0" "allow_other,blksize=4096,blksize=4096,default_permissions,group_id=0,${phase},user_id=0" "allow_other,blksize=4096,default_permissions,group_id=0,${phase},user_id=0,uid=1000" "allow_other,blksize=4096,default_permissions,group_id=0,nodev,${phase},user_id=0" "allow_other,blksize=4096,default_permissions,group_id=0,${phase},user_id=0,arbitrary" ) for candidate in "${invalid_fs[@]}"; do assert_fails _swr_mount_options_are_safe "$phase" "$vfs" "$candidate" done done } review_mount_option_whitespace_is_lossless() { local canonical_vfs='nodev,noexec,nosuid,relatime,ro' local canonical_fs='allow_other,blksize=4096,default_permissions,group_id=0,ro,user_id=0' local field whitespace candidate json _swr_source='' _swr_target='' local _swr_fstype='' _swr_vfs='' _swr_fs='' # Production breaks caught: read/here-string parsing must not discard a # suffix, and JSON field framing must not let one field become another. assert_fails _swr_mount_options_are_safe ro "$canonical_vfs" "$canonical_fs"$'\n' assert_fails _swr_mount_options_are_safe ro "$canonical_vfs" "$canonical_fs"$'\nunknown' assert_fails _swr_mount_options_are_safe ro "$canonical_vfs"$'\n' "$canonical_fs" assert_fails _swr_mount_options_are_safe ro "$canonical_vfs"$'\nunknown' "$canonical_fs" for field in vfs fs; do for whitespace in ' ' $'\t' $'\r' $'\n'; do if [[ "$field" == vfs ]]; then candidate="${canonical_vfs/relatime/relatime${whitespace}}" assert_fails _swr_mount_options_are_safe ro "$candidate" "$canonical_fs" else candidate="${canonical_fs/default_permissions/default_permissions${whitespace}}" assert_fails _swr_mount_options_are_safe ro "$canonical_vfs" "$candidate" fi done done for json in \ '{"filesystems":[{"source":"/dev/fixture recovery","target":"/run/user/1000/mount","fstype":"fuseblk","vfs-options":"nodev,noexec,nosuid,relatime,ro","fs-options":"allow_other,blksize=4096,default_permissions,group_id=0,ro,user_id=0"}]}' \ '{"filesystems":[{"source":"/dev/fixture","target":"/run/user/1000/mount\tforeign","fstype":"fuseblk","vfs-options":"nodev,noexec,nosuid,relatime,ro","fs-options":"allow_other,blksize=4096,default_permissions,group_id=0,ro,user_id=0"}]}' \ '{"filesystems":[{"source":"/dev/fixture","target":"/run/user/1000/mount","fstype":"fuseblk\r","vfs-options":"nodev,noexec,nosuid,relatime,ro","fs-options":"allow_other,blksize=4096,default_permissions,group_id=0,ro,user_id=0"}]}' \ '{"filesystems":[{"source":"/dev/fixture","target":"/run/user/1000/mount","fstype":"fuseblk","vfs-options":"nodev,noexec,nosuid,relatime,ro\nallow_other,blksize=4096,default_permissions,group_id=0,ro,user_id=0","fs-options":""}]}' \ '{"filesystems":[{"source":"/dev/fixture","target":"/run/user/1000/mount","fstype":"fuseblk","vfs-options":"nodev,noexec,nosuid,relatime,ro","fs-options":"allow_other,blksize=4096,default_permissions,group_id=0,ro,user_id=0\n"}]}'; do assert_fails _swr_parse_findmnt_json "$json" _swr_source _swr_target \ _swr_fstype _swr_vfs _swr_fs done } review_validate_mount_rejects_json_whitespace_reframing() { local fake_case _swr_created='' reset_fake_boundary _swr_create_mountpoint _swr_created || fail 'JSON whitespace mountpoint creation failed' fake_mountpoint="$_swr_created" builtin printf '%s\n' ro >"$fake_mount_state" for fake_case in \ json_fs_trailing_lf json_fs_trailing_lf_garbage json_vfs_cross_field_reframe; do builtin printf '%s\n' "$fake_case" >"$fake_case_file" assert_fails _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro done builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" } review_cycle_uncertain_cleanup() { local status rc _swr_created='' mounts umounts for status in 32 124 255; do reset_fake_boundary fake_action=mutation _swr_create_mountpoint _swr_created || fail 'uncertain-cycle mountpoint creation failed' fake_mountpoint="$_swr_created" builtin printf '%s\n' "$status" >"$fake_mount_status" builtin printf '%s\n' 1 >"$fake_mount_uncertain" builtin printf '%s\n' source_rc1_nonempty_poll2 >"$fake_case_file" if _swr_run_volume_cycle /dev/fixture-recovery-partition "$fake_mountpoint" >/dev/null 2>&1; then rc=0 else rc=$? fi assert_eq 1 "$rc" "cleanup ambiguity did not win after mount status $status" mounts="$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/ntfs-3g\t-o' "$fake_log")" umounts="$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/umount\t--' "$fake_log")" assert_eq 1 "$mounts" "mount status $status triggered a later writable mount" assert_eq 1 "$umounts" "mount status $status unmount count differs" assert_eq 2 "$(<"$fake_source_query_count")" "mount status $status source absence query count differs" assert_eq 0 "$(<"$fake_action_count")" "mount status $status invoked the volume action" builtin printf '%s\n' absent >"$fake_mount_state" builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" done reset_fake_boundary fake_action=mutation _swr_create_mountpoint _swr_created || fail 'validation-cycle mountpoint creation failed' fake_mountpoint="$_swr_created" builtin printf '%s\n' foreign_source >"$fake_case_file" _swr_run_volume_cycle /dev/fixture-recovery-partition "$fake_mountpoint" >/dev/null 2>&1 && fail 'mounted validation failure was accepted' assert_eq 1 "$(/usr/bin/grep -Fc $'/usr/bin/sudo\t-n\t/usr/bin/timeout\t--signal=TERM\t--kill-after=10s\t45s\t/usr/bin/umount\t--' "$fake_log")" 'validation failure unmount count differs' assert_eq 2 "$(<"$fake_source_query_count")" 'validation failure source absence query count differs' assert_eq 0 "$(<"$fake_action_count")" 'validation failure invoked the volume action' builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" } review_runtime_root_uses_fixed_command_leaf() { local direct_marker="$fixture_dir/direct-runtime-readlink" resolved='' reset_fake_boundary builtin eval "$production_runtime_root_definition" function /usr/bin/readlink() { builtin printf '%s\n' direct >"$direct_marker" return 98 } if ! resolved="$(_swr_runtime_root)"; then [[ ! -e "$direct_marker" ]] || fail 'runtime root resolution bypassed fixed command leaf' fail 'intercepted runtime root resolution failed' fi [[ ! -e "$direct_marker" ]] || fail 'runtime root resolution bypassed fixed command leaf' assert_eq /run/user/1000 "$resolved" 'fixed runtime root result differs' assert_log_line $'/usr/bin/readlink\t-e\t--\t/run/user/1000' 'runtime root fixed command leaf argv differs' } run_review_case() { local function_name="$1" shift if ( "$function_name" "$@" ); then pass_boundary_case else review_failures=$((review_failures + 1)) fi } test_review_fix_round_one() { run_review_case review_findmnt_initial_rc1_nonempty run_review_case review_findmnt_post_poll1_rc1_nonempty run_review_case review_findmnt_post_poll2_rc1_nonempty run_review_case review_findmnt_rc1_overflow run_review_case review_sudo_after_complete_preflight run_review_case review_sudo_failure_cleans_owned_mountpoint run_review_case review_preflight_failure_has_no_privileged_call run_review_case review_mount_option_conflicts run_review_case review_normalized_mount_option_grammar_both_phases run_review_case review_mount_option_whitespace_is_lossless run_review_case review_validate_mount_rejects_json_whitespace_reframing run_review_case review_cycle_uncertain_cleanup run_review_case review_runtime_root_uses_fixed_command_leaf (( review_failures == 0 )) || fail "Task 4 review regressions failed: $review_failures" } review_findmnt_newline_initial() { local fake_case="$1" label="$2" reset_fake_boundary builtin printf '%s\n' "$fake_case" >"$fake_case_file" _swr_require_unmounted /dev/fixture-recovery-partition && fail "findmnt RC1 newline-only $label initial output was accepted as absence" return 0 } review_findmnt_newline_post_unmount() { local fake_case="$1" label="$2" reset_fake_boundary builtin printf '%s\n' ro >"$fake_mount_state" builtin printf '%s\n' "$fake_case" >"$fake_case_file" _swr_unmount_volume /dev/fixture-recovery-partition "$fake_mountpoint" >/dev/null 2>&1 && fail "findmnt RC1 newline-only $label post-unmount output was accepted as absence" return 0 } review_mount_uncharacterized_extras() { local field="$1" rejection _swr_created='' local -a rejections=() reset_fake_boundary _swr_create_mountpoint _swr_created || fail 'unknown-extra mountpoint creation failed' fake_mountpoint="$_swr_created" builtin printf '%s\n' ro >"$fake_mount_state" case "$field" in vfs) rejections=(vfs_permissions vfs_acl vfs_inherit vfs_unknown) ;; fs) rejections=(fs_permissions fs_acl fs_inherit fs_unknown) ;; *) fail 'unknown option field selector' ;; esac for rejection in "${rejections[@]}"; do builtin printf '%s\n' "$rejection" >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro >/dev/null 2>&1 && fail "uncharacterized $field mount option was accepted: $rejection" done builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" } review_mount_malformed_csv() { local rejection _swr_created='' local -a rejections=( vfs_trailing_comma fs_trailing_comma vfs_empty vfs_leading_comma vfs_double_comma fs_empty fs_leading_comma fs_double_comma ) reset_fake_boundary _swr_create_mountpoint _swr_created || fail 'malformed-CSV mountpoint creation failed' fake_mountpoint="$_swr_created" builtin printf '%s\n' ro >"$fake_mount_state" for rejection in "${rejections[@]}"; do builtin printf '%s\n' "$rejection" >"$fake_case_file" _swr_validate_mount /dev/fixture-recovery-partition "$fake_mountpoint" ro >/dev/null 2>&1 && fail "malformed mount option CSV was accepted: $rejection" done builtin printf '%s\n' valid >"$fake_case_file" command /usr/bin/rmdir -- "$fake_mountpoint" } test_review_fix_round_two() { run_review_case review_findmnt_newline_initial source_rc1_newline_1 one-LF run_review_case review_findmnt_newline_initial source_rc1_newline_2 two-LF run_review_case review_findmnt_newline_initial source_rc1_newline_overflow over-16KiB-LF run_review_case review_findmnt_newline_post_unmount source_rc1_newline_1 one-LF run_review_case review_findmnt_newline_post_unmount source_rc1_newline_2 two-LF run_review_case review_findmnt_newline_post_unmount source_rc1_newline_overflow over-16KiB-LF run_review_case review_mount_uncharacterized_extras vfs run_review_case review_mount_uncharacterized_extras fs run_review_case review_mount_malformed_csv (( review_failures == 0 )) || fail "Task 4 review round 2 regressions failed: $review_failures" } review_mountpoint_path_is_prearmed_before_attestation() { local failure="$1" _swr_created='' foreign="$fixture_dir/foreign-mount-target" mkdir -p -m 0700 -- "$foreign" _swr_runtime_root() { builtin printf '%s\n' "$fake_runtime_root"; } _swr_command() { if [[ "$1:$failure" == /usr/bin/chmod:chmod ]]; then return 1 fi if [[ "$1:$failure" == /usr/bin/stat:attest ]]; then return 1 fi if [[ "$1:$failure" == /usr/bin/chmod:foreign ]]; then command /usr/bin/rmdir -- "${@: -1}" command /usr/bin/ln -s -- "$foreign" "${@: -1}" return 1 fi command "$@" } _swr_create_mountpoint _swr_created && fail "mountpoint $failure failure was accepted" [[ "$_swr_created" == "$fake_runtime_root/slack-webhook-recovery."* ]] || fail "mountpoint $failure path was not prearmed" if [[ "$failure" == foreign ]]; then [[ -L "$_swr_created" && "$(command /usr/bin/readlink -- "$_swr_created")" == "$foreign" ]] || fail 'foreign mountpoint replacement was removed' elif [[ -d "$_swr_created" ]]; then failure=cleanup _swr_remove_mountpoint "$_swr_created" || true [[ ! -e "$_swr_created" ]] || fail "owned mountpoint $failure residue remained" fi } review_prepare_publishes_partial_mountpoint() { local _swr_work='' _swr_device='' _swr_mount='' _swr_load_recovery_contract() { return 0; } _swr_resolve_device() { builtin printf -v "$1" '%s' /dev/fixture; } _swr_require_unmounted() { return 0; } _swr_runtime_root() { builtin printf '%s\n' /run/user/1000; } _swr_capture_single_line() { local name="$1"; shift case "$*" in '/usr/bin/stat --format=%u:%g:%a -- /run/user/1000') builtin printf -v "$name" '%s' 1000:1000:700 ;; '/usr/bin/stat --file-system --format=%T -- /run/user/1000') builtin printf -v "$name" '%s' tmpfs ;; '/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX') builtin printf -v "$name" '%s' /run/user/1000/platform-slack-keepass.SYNTHETIC ;; *) return 1 ;; esac } _swr_command() { return 0; } _swr_work_root_is_safe() { return 0; } _swr_create_mountpoint() { builtin printf -v "$1" '%s' /run/user/1000/slack-webhook-recovery.SYNTHETIC return 1 } _swr_prepare_transaction _swr_work _swr_device _swr_mount /fixture/webhook /fixture/contract && fail 'partial mountpoint preparation failure was accepted' assert_eq /run/user/1000/slack-webhook-recovery.SYNTHETIC "$_swr_mount" \ 'preparation did not publish the partial mountpoint' } review_stop_vault_tears_down_failed_persistent_client() { local socket="$fixture_dir/stop-failure.sock" vault_pid='' client_pid='' /usr/bin/python3 -c 'import socket,sys,time; s=socket.socket(socket.AF_UNIX); s.bind(sys.argv[1]); time.sleep(30)' "$socket" & vault_pid=$! /usr/bin/sleep 0.05 /usr/bin/sleep 30 & client_pid=$! trap 'kill -TERM '"$vault_pid"' '"$client_pid"' 2>/dev/null || true; wait '"$vault_pid"' '"$client_pid"' 2>/dev/null || true' EXIT exec {_SWR_VAULT_CLIENT_READ_FD}/dev/null _SWR_VAULT_CLIENT_SOCKET="$socket" _SWR_VAULT_CLIENT_PID="$client_pid" _swr_vault_request() { return 1; } _swr_stop_vault "$socket" "$vault_pid" && fail 'failed SHUTDOWN was accepted' [[ -z "$_SWR_VAULT_CLIENT_SOCKET$_SWR_VAULT_CLIENT_PID$_SWR_VAULT_CLIENT_READ_FD$_SWR_VAULT_CLIENT_WRITE_FD" ]] || fail 'failed SHUTDOWN retained persistent client state' kill -0 "$client_pid" 2>/dev/null && fail 'failed SHUTDOWN retained persistent client process' trap - EXIT } test_start_vault_waits_for_delayed_operator_input() { # Production break caught: the coordinator kills the healthy vault after # five seconds even though the vault intentionally withholds its socket # until both operator inputs have been retained. local repository="$fixture_dir/delayed-vault-repository" local runtime="$fixture_dir/delayed-vault-runtime" local helper="$repository/scripts/libexec/slack-webhook-recovery-vault.py" local webhook="$fixture_dir/delayed-vault-webhook" input_fifo="$fixture_dir/delayed-vault-webhook.input" local pre_input="$fixture_dir/delayed-vault-pre-input" helper_pid_file="$runtime/helper.pid" local saved_repository_root="$SWR_REPOSITORY_ROOT" local _swr_delayed_pid='' _swr_delayed_socket='' writer_pid='' helper_pid='' start_rc=0 stop_rc=1 mkdir -p -m 0700 -- "${helper%/*}" "$runtime" builtin printf '%s\n' \ 'import os' \ 'import socket' \ 'import sys' \ 'runtime = sys.argv[sys.argv.index("--runtime-root") + 1]' \ 'socket_path = os.path.join(runtime, "vault.sock")' \ 'with open(os.path.join(runtime, "helper.pid"), "w", encoding="ascii") as stream:' \ ' stream.write(str(os.getpid()))' \ 'input_path = sys.argv[sys.argv.index("--webhook-file") + 1] + ".input"' \ 'with open(input_path, "rb", buffering=0) as input_stream:' \ ' if not input_stream.readline() or not input_stream.readline():' \ ' raise SystemExit(70)' \ 'server = socket.socket(socket.AF_UNIX)' \ 'try:' \ ' server.bind(socket_path)' \ ' os.chmod(socket_path, 0o600)' \ ' server.listen(1)' \ ' connection, _ = server.accept()' \ ' with connection:' \ ' command = b""' \ ' while not command.endswith(b"\\n"):' \ ' command += connection.recv(64)' \ ' if command != b"SHUTDOWN\\n":' \ ' raise SystemExit(71)' \ ' connection.sendall(b"stopped\\n")' \ 'finally:' \ ' server.close()' \ ' if os.path.exists(socket_path):' \ ' os.unlink(socket_path)' >"$helper" chmod 0600 -- "$helper" builtin printf '%s\n' synthetic-webhook >"$webhook" chmod 0600 -- "$webhook" mkfifo -m 0600 -- "$input_fifo" ( exec 3<>"$input_fifo" /usr/bin/sleep 5.2 if [[ -e "$runtime/vault.sock" || -L "$runtime/vault.sock" ]]; then builtin printf '%s\n' published >"$pre_input" else builtin printf '%s\n' absent >"$pre_input" fi builtin printf '%s\n' synthetic-app synthetic-input >&3 ) & writer_pid=$! SWR_REPOSITORY_ROOT="$repository" set +e _swr_start_vault _swr_delayed_pid _swr_delayed_socket "$runtime" "$webhook" start_rc=$? set -e SWR_REPOSITORY_ROOT="$saved_repository_root" wait "$writer_pid" 2>/dev/null || true if (( start_rc == 0 )); then helper_pid="$(<"$helper_pid_file")" [[ "$(<"$pre_input")" == absent ]] || start_rc=72 [[ "$_swr_delayed_socket" == "$runtime/vault.sock" && -S "$_swr_delayed_socket" ]] || start_rc=73 [[ "$_swr_delayed_pid" == "$helper_pid" ]] || start_rc=74 /usr/bin/sleep 0.1 kill -0 "$_swr_delayed_pid" 2>/dev/null || start_rc=75 if (( start_rc == 0 )); then set +e _swr_terminate_vault_child "$_swr_delayed_pid" stop_rc=$? set -e fi elif [[ -f "$helper_pid_file" ]]; then helper_pid="$(<"$helper_pid_file")" fi if [[ "$helper_pid" =~ ^[1-9][0-9]*$ ]] && kill -0 "$helper_pid" 2>/dev/null; then kill -TERM "$_swr_delayed_pid" "$helper_pid" 2>/dev/null || true wait "$_swr_delayed_pid" 2>/dev/null || true fi rm -f -- "$input_fifo" "$runtime/vault.sock" assert_eq 0 "$start_rc" 'vault startup rejected operator input delayed beyond five seconds' assert_eq 0 "$stop_rc" "delayed-input vault did not stop cleanly (rc=$stop_rc)" [[ ! "$helper_pid" =~ ^[1-9][0-9]*$ ]] || ! kill -0 "$helper_pid" 2>/dev/null || fail 'delayed-input vault helper remained alive' } test_vault_readiness_failure_boundaries() { # Production breaks caught: unbounded readiness, zombie blindness, # signal deferral through the full human window, foreign-path deletion, # and TERM-only cleanup that can orphan a resistant child. local root="$fixture_dir/vault-readiness-boundaries" socket="$fixture_dir/vault-readiness-boundaries/vault.sock" local pid='' rc=0 code started_ns ended_ns elapsed_ms mkdir -m 0700 -- "$root" /usr/bin/python3 -c 'import time; time.sleep(30)' & pid=$! set +e _swr_wait_vault_ready "$socket" "$pid" 2 rc=$? set -e assert_eq 1 "$rc" 'short vault readiness deadline was accepted' _swr_terminate_vault_child "$pid" ! kill -0 "$pid" 2>/dev/null || fail 'deadline cleanup retained vault child' /usr/bin/python3 -c 'raise SystemExit(17)' & pid=$! started_ns="$(/usr/bin/date +%s%N)" set +e _swr_wait_vault_ready "$socket" "$pid" 100 rc=$? set -e ended_ns="$(/usr/bin/date +%s%N)" elapsed_ms=$(((ended_ns - started_ns) / 1000000)) assert_eq 1 "$rc" 'dead vault child was accepted as waiting' (( elapsed_ms < 1000 )) || fail 'dead vault child did not fail promptly' wait "$pid" 2>/dev/null || true builtin printf '%s\n' foreign >"$socket" /usr/bin/python3 -c 'import time; time.sleep(30)' & pid=$! set +e _swr_wait_vault_ready "$socket" "$pid" 2 rc=$? set -e assert_eq 1 "$rc" 'foreign vault socket path was accepted' assert_eq foreign "$(<"$socket")" 'foreign vault socket path was changed' _swr_terminate_vault_child "$pid" rm -f -- "$socket" for code in 129 130 143; do /usr/bin/python3 -c 'import time; time.sleep(30)' & pid=$! SWR_PENDING_SIGNAL="$code" set +e _swr_wait_vault_ready "$socket" "$pid" 100 rc=$? set -e assert_eq 2 "$rc" "pending signal $code did not win vault readiness boundary" _swr_terminate_vault_child "$pid" ! kill -0 "$pid" 2>/dev/null || fail "pending signal $code retained vault child" assert_eq "$code" "$SWR_PENDING_SIGNAL" "pending signal $code changed during cleanup" done SWR_PENDING_SIGNAL=0 /usr/bin/python3 -c 'import signal,time; signal.signal(signal.SIGTERM, signal.SIG_IGN); time.sleep(30)' & pid=$! /usr/bin/sleep 0.05 started_ns="$(/usr/bin/date +%s%N)" _swr_terminate_vault_child "$pid" ended_ns="$(/usr/bin/date +%s%N)" elapsed_ms=$(((ended_ns - started_ns) / 1000000)) (( elapsed_ms < 3000 )) || fail 'TERM-resistant vault cleanup exceeded bound' ! kill -0 "$pid" 2>/dev/null || fail 'TERM-resistant vault child remained alive' } test_pending_signal_after_readiness_prevents_publication() { # Production break caught: a signal delivered after readiness returns but # before output publication exposes a live socket/PID and is not forwarded # to the vault until generic SHUTDOWN cleanup. local repository="$fixture_dir/post-ready-signal-repository" local helper="$repository/scripts/libexec/slack-webhook-recovery-vault.py" local runtime webhook saved_repository_root="$SWR_REPOSITORY_ROOT" local saved_wait_definition signal_name code signum helper_pid rc local _swr_signal_pid _swr_signal_socket saved_wait_definition="$(declare -f _swr_wait_vault_ready)" mkdir -p -m 0700 -- "${helper%/*}" builtin printf '%s\n' \ 'import os' \ 'import signal' \ 'import sys' \ 'runtime = sys.argv[sys.argv.index("--runtime-root") + 1]' \ 'signal_file = os.path.join(runtime, "signal")' \ 'def finish(signum, _frame):' \ ' with open(signal_file, "w", encoding="ascii") as stream:' \ ' stream.write(str(signum))' \ ' raise SystemExit(128 + signum)' \ 'for signum in (signal.SIGHUP, signal.SIGINT, signal.SIGTERM):' \ ' signal.signal(signum, finish)' \ 'with open(os.path.join(runtime, "helper.pid"), "w", encoding="ascii") as stream:' \ ' stream.write(str(os.getpid()))' \ 'signal.pause()' >"$helper" chmod 0600 -- "$helper" for signal_name in HUP INT TERM; do case "$signal_name" in HUP) code=129; signum=1 ;; INT) code=130; signum=2 ;; TERM) code=143; signum=15 ;; esac runtime="$fixture_dir/post-ready-signal-$signal_name" webhook="$fixture_dir/post-ready-signal-$signal_name-webhook" mkdir -m 0700 -- "$runtime" builtin printf synthetic >"$webhook"; chmod 0600 -- "$webhook" _swr_wait_vault_ready() { local index for (( index = 0; index < 100; index++ )); do [[ -f "$runtime/helper.pid" ]] && break /usr/bin/sleep 0.01 done [[ -f "$runtime/helper.pid" ]] || return 1 SWR_PENDING_SIGNAL="$code" return 0 } SWR_REPOSITORY_ROOT="$repository" _swr_signal_pid=sentinel-pid _swr_signal_socket=sentinel-socket set +e _swr_start_vault _swr_signal_pid _swr_signal_socket "$runtime" "$webhook" rc=$? set -e SWR_REPOSITORY_ROOT="$saved_repository_root" helper_pid="$(<"$runtime/helper.pid")" if kill -0 "$helper_pid" 2>/dev/null; then kill -KILL "$helper_pid" 2>/dev/null || true wait "$helper_pid" 2>/dev/null || true fi assert_eq 1 "$rc" "post-ready $signal_name signal was accepted" assert_eq sentinel-pid "$_swr_signal_pid" "post-ready $signal_name published vault PID" assert_eq sentinel-socket "$_swr_signal_socket" "post-ready $signal_name published socket" assert_eq "$signum" "$(<"$runtime/signal")" "post-ready $signal_name was not forwarded" ! kill -0 "$helper_pid" 2>/dev/null || fail "post-ready $signal_name retained vault child" SWR_PENDING_SIGNAL=0 done eval "$saved_wait_definition" } review_work_root_inventory_precedes_deletion() { local case_name="$1" root baseline violation='' _swr_command() { command "$@"; } root="$(/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX)" chmod 0700 -- "$root" baseline="$root/baseline.kdbx" builtin printf x >"$baseline"; chmod 0600 -- "$baseline" case "$case_name" in unexpected) builtin printf y >"$root/unexpected"; chmod 0600 -- "$root/unexpected" _swr_remove_work_root "$root" && violation='unexpected work-root content was accepted' [[ -f "$baseline" ]] || violation='inventory deleted known evidence before finding unexpected content' /usr/bin/rm -f -- "$root/unexpected" "$baseline" ;; wrong-mode) builtin printf y >"$root/current.kdbx"; chmod 0644 -- "$root/current.kdbx" _swr_remove_work_root "$root" && violation='wrong-mode work-root content was accepted' [[ -f "$baseline" ]] || violation='inventory deleted known evidence before finding wrong mode' /usr/bin/rm -f -- "$root/current.kdbx" "$baseline" ;; *) fail 'unknown topology case' ;; esac /usr/bin/rmdir -- "$root" [[ -z "$violation" ]] || fail "$violation" } review_failed_find_inventory_preserves_work_root() { local producer="$1" root baseline violation='' root="$(/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX)" chmod 0700 -- "$root" baseline="$root/baseline.kdbx" builtin printf x >"$baseline"; chmod 0600 -- "$baseline" _swr_command() { if [[ "$1" == /usr/bin/find && "$producer" == root && "$2" == "$root" && "$3" == -mindepth ]]; then builtin printf '%s\n' baseline.kdbx return 71 fi command "$@" } _swr_remove_work_root "$root" && violation="$producer failed inventory was accepted" [[ -f "$baseline" ]] || violation="$producer failed inventory deleted evidence" _swr_command() { command "$@"; } /usr/bin/rm -f -- "$baseline" /usr/bin/rmdir -- "$root" [[ -z "$violation" ]] || fail "$violation" } review_work_root_rejects_unexpected_vault_home() { local root baseline violation='' root="$(/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX)" chmod 0700 -- "$root" baseline="$root/baseline.kdbx" builtin printf x >"$baseline"; chmod 0600 -- "$baseline" mkdir -m 0700 -- "$root/vault-home" _swr_command() { command "$@"; } _swr_remove_work_root "$root" && violation='unexpected vault-home was accepted' [[ -f "$baseline" ]] || violation='unexpected vault-home deleted known evidence' [[ -d "$root/vault-home" ]] || violation='unexpected vault-home was deleted' [[ ! -d "$root/vault-home" ]] || /usr/bin/rmdir -- "$root/vault-home" [[ ! -f "$baseline" ]] || /usr/bin/rm -f -- "$baseline" [[ ! -d "$root" ]] || /usr/bin/rmdir -- "$root" [[ -z "$violation" ]] || fail "$violation" } review_nul_inventory_rejects_ambiguous_or_partial_name() { local inventory_case="$1" root baseline hostile violation='' root="$(/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX)" chmod 0700 -- "$root" baseline="$root/baseline.kdbx" builtin printf x >"$baseline"; chmod 0600 -- "$baseline" hostile="$root/"$'baseline.kdbx\ncurrent.kdbx' if [[ "$inventory_case" == lf-name ]]; then builtin printf y >"$hostile"; chmod 0600 -- "$hostile" _swr_command() { command "$@"; } else _swr_command() { if [[ "$1" == /usr/bin/find && "$2" == "$root" && "$3" == -mindepth ]]; then builtin printf '%s' baseline.kdbx return 0 fi command "$@" } fi _swr_remove_work_root "$root" && violation="$inventory_case inventory was accepted" [[ -f "$baseline" ]] || violation="$inventory_case inventory deleted known evidence" _swr_command() { command "$@"; } /usr/bin/rm -f -- "$baseline" [[ ! -e "$hostile" ]] || /usr/bin/rm -f -- "$hostile" /usr/bin/rmdir -- "$root" [[ -z "$violation" ]] || fail "$violation" } review_inventory_stops_at_bounded_input_limit() { local inventory_case="$1" caller="$2" root baseline producer_pid='' violation='' local complete_marker="$fixture_dir/inventory-${inventory_case}-${caller}.complete" local pid_marker="$fixture_dir/inventory-${inventory_case}-${caller}.pid" local -a _swr_inventory=() root="$(/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX)" chmod 0700 -- "$root" baseline="$root/baseline.kdbx" builtin printf x >"$baseline"; chmod 0600 -- "$baseline" _swr_command() { if [[ "$1" == /usr/bin/find && "$2" == "$root" && "$3" == -mindepth ]]; then builtin printf '%s' "$BASHPID" >"$pid_marker" local chunk='' record='' index case "$inventory_case" in long-non-nul) builtin printf -v chunk '%256s' '' chunk="${chunk// /x}" for (( index = 0; index < 8192; index++ )); do builtin printf '%s' "$chunk" || return 74 done ;; count-total-overflow) for (( index = 0; index < 10000; index++ )); do builtin printf -v record 'n%0254d' "$index" builtin printf '%s\0' "$record" || return 75 done ;; *) return 97 ;; esac builtin printf complete >"$complete_marker" return 0 fi command "$@" } if [[ "$caller" == parser ]]; then _swr_inventory_directory _swr_inventory "$root" && violation="$inventory_case bounded inventory was accepted" if [[ "$inventory_case" == long-non-nul ]]; then (( ${#_swr_inventory[@]} == 0 )) || violation="$inventory_case retained an overlong record" else (( ${#_swr_inventory[@]} == 16 )) || violation="$inventory_case retained ${#_swr_inventory[@]} records after limit" fi else _swr_remove_work_root "$root" && violation="$inventory_case work-root cleanup accepted failed inventory" fi [[ -n "$violation" || ! -e "$complete_marker" ]] || violation="$inventory_case consumed the entire lazy producer" producer_pid="$(<"$pid_marker")" [[ "$producer_pid" =~ ^[1-9][0-9]*$ ]] || violation="$inventory_case producer PID was not captured" if [[ "$producer_pid" =~ ^[1-9][0-9]*$ ]] && kill -0 "$producer_pid" 2>/dev/null; then violation="$inventory_case producer was not terminated and waited" fi [[ -f "$baseline" ]] || violation="$inventory_case inventory deleted evidence" _swr_command() { command "$@"; } /usr/bin/rm -f -- "$baseline" "$complete_marker" "$pid_marker" /usr/bin/rmdir -- "$root" [[ -z "$violation" ]] || fail "$violation" } test_task5_fix_round_one_boundaries() { run_review_case review_mountpoint_path_is_prearmed_before_attestation chmod run_review_case review_mountpoint_path_is_prearmed_before_attestation attest run_review_case review_mountpoint_path_is_prearmed_before_attestation foreign run_review_case review_prepare_publishes_partial_mountpoint run_review_case review_stop_vault_tears_down_failed_persistent_client run_review_case review_work_root_inventory_precedes_deletion unexpected run_review_case review_work_root_inventory_precedes_deletion wrong-mode run_review_case review_failed_find_inventory_preserves_work_root root run_review_case review_work_root_rejects_unexpected_vault_home run_review_case review_nul_inventory_rejects_ambiguous_or_partial_name lf-name run_review_case review_nul_inventory_rejects_ambiguous_or_partial_name partial-frame (( review_failures == 0 )) || fail "Task 5 fix round one regressions failed: $review_failures" } test_task5_fix_round_four_inventory_boundaries() { run_review_case review_inventory_stops_at_bounded_input_limit long-non-nul parser run_review_case review_inventory_stops_at_bounded_input_limit long-non-nul cleanup run_review_case review_inventory_stops_at_bounded_input_limit count-total-overflow parser run_review_case review_inventory_stops_at_bounded_input_limit count-total-overflow cleanup (( review_failures == 0 )) || fail "Task 5 fix round four regressions failed: $review_failures" } transaction_log_event() { builtin printf '%s\n' "$1" >>"$transaction_log" } _swr_fake_signal_after_event() { local event="$1" signal_name scenario_event [[ "$transaction_scenario" == signal-* ]] || return 0 signal_name="${transaction_scenario#signal-}" signal_name="${signal_name%%-*}" scenario_event="${transaction_scenario#signal-${signal_name}-}" [[ "$scenario_event" == "$event" ]] || return 0 kill -"$signal_name" "$BASHPID" } reset_transaction_fake() { : >"$transaction_log" transaction_phase=ro transaction_commit_calls=0 SWR_TRANSACTION_STATE='' SWR_PENDING_SIGNAL=0 } _swr_fake_prepare_transaction() { transaction_log_event validate-runtime builtin printf -v "$1" '%s' /fixture/work-root builtin printf -v "$2" '%s' /dev/fixture-recovery-partition builtin printf -v "$3" '%s' /fixture/mountpoint _swr_fake_signal_after_event validate-runtime } _swr_fake_start_transaction_vault() { transaction_log_event start-vault-and-retain-inputs builtin printf -v "$1" '%s' 4242 builtin printf -v "$2" '%s' /fixture/work-root/vault.sock _swr_fake_signal_after_event start-vault-and-retain-inputs } _swr_fake_refresh_sudo() { transaction_log_event sudo-refresh _swr_fake_signal_after_event sudo-refresh } _swr_fake_probe_transaction_rw() { transaction_log_event "probe-${transaction_phase}-safety" [[ "$transaction_scenario:$transaction_phase" == term-rw-probe:rw ]] && kill -TERM "$BASHPID" _swr_fake_signal_after_event "probe-${transaction_phase}-safety" return 0 } _swr_fake_mount_transaction_volume() { transaction_phase="$3" transaction_log_event "mount-${transaction_phase}" _swr_fake_signal_after_event "mount-${transaction_phase}" case "$transaction_scenario:$transaction_phase" in mount-ro-failure:ro|mount-ro-response-loss-unresolved-source:ro) return 32 ;; esac } _swr_fake_validate_transaction_mount() { transaction_log_event "validate-${3}-mount" [[ "$transaction_scenario:$3" == int-rw-validate:rw ]] && kill -INT "$BASHPID" _swr_fake_signal_after_event "validate-${3}-mount" case "$transaction_scenario:$3" in validate-ro-wrong-uid:ro|validate-ro-wrong-gid:ro|validate-ro-wrong-mode:ro) return 1 ;; esac return 0 } _swr_fake_dirfd_snapshot() { transaction_log_event snapshot _swr_fake_signal_after_event snapshot } _swr_fake_unmount_transaction_volume() { transaction_log_event "unmount-${transaction_phase}" _swr_fake_signal_after_event "unmount-${transaction_phase}" [[ "$transaction_scenario:$transaction_phase" == hup-final-unmount:rw ]] && kill -HUP "$BASHPID" case "$transaction_scenario:$transaction_phase" in mount-ro-response-loss-unresolved-source:ro) return 1 ;; unmount-ro:ro|unmount-rw:rw|unmount-ambiguous:*) return 1 ;; esac } _swr_fake_transaction_stably_unmounted() { case "$transaction_scenario" in mount-ro-response-loss-unresolved-source|unmount-ro|unmount-rw|unmount-ambiguous) return 1 ;; esac } _swr_fake_vault_transaction_request() { local result_name="$1" command="$3" reply='' case "$command" in PREPARE) transaction_log_event classify _swr_fake_signal_after_event classify case "$transaction_scenario" in noop) reply=exact-noop ;; hup-noop) kill -HUP "$BASHPID"; reply=exact-noop ;; signal-INT-confirm-update) reply=mismatch ;; absent|original-drift|backup-collision|backup-fsync|rename-failure|post-rename|final-verification|hup-before|int-before|term-before|hup-during|int-during|term-during|term-rw-probe|int-rw-validate|lost-helper|lost-after-verified|hup-final-unmount|term-cleanup|term-post-cleanup|unmount-ro|unmount-rw|unmount-ambiguous|signal-*) reply=absent ;; mismatch-no-update|mismatch-update) reply=mismatch ;; duplicate) reply=ambiguous ;; wrong-master|retained-input-drift) reply=failed ;; *) return 97 ;; esac ;; 'BUILD ADD') transaction_log_event build-add; _swr_fake_signal_after_event build-add; reply=candidate-ready ;; 'BUILD UPDATE') transaction_log_event build-update; _swr_fake_signal_after_event build-update; reply=candidate-ready ;; VERIFY_CANDIDATE) transaction_log_event verify-candidate; _swr_fake_signal_after_event verify-candidate; reply=verified ;; 'VERIFY_COMMITTED '*) transaction_log_event verify-committed-copy [[ "$transaction_scenario" == final-verification ]] && reply=failed || reply=verified ;; *) return 97 ;; esac builtin printf -v "$result_name" '%s' "$reply" } _swr_fake_confirm_transaction() { local expected="$1" transaction_log_event "confirm-${expected,,}" _swr_fake_signal_after_event "confirm-${expected,,}" case "$transaction_scenario:$expected" in mismatch-no-update:UPDATE) return 1 ;; hup-before:WRITE) kill -HUP "$BASHPID"; return 1 ;; int-before:WRITE) kill -INT "$BASHPID"; return 1 ;; term-before:WRITE) kill -TERM "$BASHPID"; return 1 ;; esac [[ "$expected" == WRITE ]] && transaction_phase=rw return 0 } _swr_fake_dirfd_commit() { local result_name="$1" transaction_commit_calls=$((transaction_commit_calls + 1)) transaction_log_event commit case "$transaction_scenario" in original-drift|backup-collision|backup-fsync) builtin printf -v "$result_name" '%s' precommit-failure return 1 ;; rename-failure|post-rename) builtin printf -v "$result_name" '%s' committed-but-uncertain return 1 ;; lost-helper) builtin printf -v "$result_name" '%s' rename-attempted return 1 ;; lost-after-verified) builtin printf -v "$result_name" '%s' verified-commit return 0 ;; hup-during) kill -HUP "$BASHPID" ;; int-during) kill -INT "$BASHPID" ;; term-during) kill -TERM "$BASHPID" ;; esac builtin printf -v "$result_name" '%s' verified-commit } _swr_fake_dirfd_snapshot_current() { transaction_log_event snapshot-current } _swr_fake_stop_transaction_vault() { transaction_log_event stop-vault [[ "$transaction_scenario" == term-cleanup ]] && kill -TERM "$BASHPID" return 0 } _swr_fake_audit_runtime_processes() { transaction_log_event audit-processes; } _swr_fake_remove_transaction_work_root() { transaction_log_event remove-work-root [[ "$transaction_scenario" == term-post-cleanup ]] && kill -TERM "$BASHPID" return 0 } assert_transaction_prefix() { local expected="$1" description="$2" actual actual="$(/usr/bin/head -n "$(builtin printf '%s\n' "$expected" | /usr/bin/wc -l)" "$transaction_log")" assert_eq "$expected" "$actual" "$description" } run_transaction_case() { local scenario="$1" expected_state="$2" expected_output="$3" expected_rc="${4-}" output='' rc=0 reset_transaction_fake transaction_scenario="$scenario" set +e execute_transaction /fixture/input-webhook /fixture/contract >"$fixture_dir/transaction.output" rc=$? set -e output="$(<"$fixture_dir/transaction.output")" [[ "$SWR_TRANSACTION_STATE" == "$expected_state" ]] || fail "$scenario terminal state differs: expected=$expected_state actual=$SWR_TRANSACTION_STATE log=$(/usr/bin/tr '\n' ' ' <"$transaction_log")" assert_eq "$expected_output" "$output" "$scenario output differs" if [[ ( "$expected_state" == NOOP || "$expected_state" == VERIFIED_COMMIT ) && -z "$expected_rc" ]]; then (( rc == 0 )) || fail "$scenario unexpectedly failed" else (( rc != 0 )) || fail "$scenario unexpectedly succeeded" [[ "$output" != *'SLACK_KEEPASS_RECOVERY=NOOP'* && "$output" != *'SLACK_KEEPASS_RECOVERY=COMMITTED'* ]] || fail "$scenario emitted a success token" fi [[ -z "$expected_rc" || "$rc" == "$expected_rc" ]] || fail "$scenario signal status differs: expected=$expected_rc actual=$rc" (( transaction_commit_calls <= 1 )) || fail "$scenario retried commit" pass_transaction_case } signal_boundary_case() { local event="$1" signal_name="${2-TERM}" expected_rc=143 output='' rc=0 later_effects [[ "$signal_name" == HUP ]] && expected_rc=129 [[ "$signal_name" == INT ]] && expected_rc=130 reset_transaction_fake transaction_scenario="signal-${signal_name}-${event}" set +e execute_transaction /fixture/input-webhook /fixture/contract >"$fixture_dir/transaction.output" rc=$? set -e output="$(<"$fixture_dir/transaction.output")" assert_eq "$expected_rc" "$rc" "signal after $event status differs" assert_eq '' "$output" "signal after $event emitted output" assert_eq PRECOMMIT_FAILURE "$SWR_TRANSACTION_STATE" \ "signal after $event rewrote precommit state" later_effects="$(/usr/bin/sed -n "0,/^${event}$/d; p" "$transaction_log" | /usr/bin/grep -Ev '^(unmount-ro|unmount-rw|stop-vault|audit-processes|remove-work-root)$' || true)" assert_eq '' "$later_effects" "signal after $event allowed a later side effect" } late_post_cleanup_signal_case() { local output='' rc=0 old_trap_marker="$fixture_dir/old-term-trap" reset_transaction_fake transaction_scenario=absent : >"$old_trap_marker" builtin trap 'builtin printf old >"$old_trap_marker"' TERM set -T builtin trap 'if [[ "$BASH_COMMAND" == *"final_rc == 0 && SWR_PENDING_SIGNAL == 0"* ]]; then builtin trap - DEBUG; kill -TERM "$BASHPID"; fi' DEBUG set +e execute_transaction /fixture/input-webhook /fixture/contract >"$fixture_dir/transaction.output" rc=$? set -e builtin trap - DEBUG set +T builtin trap - TERM output="$(<"$fixture_dir/transaction.output")" assert_eq 143 "$rc" 'post-cleanup/pre-output TERM status differs' assert_eq '' "$output" 'post-cleanup/pre-output TERM emitted output' assert_eq VERIFIED_COMMIT "$SWR_TRANSACTION_STATE" \ 'post-cleanup/pre-output TERM lost verified commit evidence' assert_eq '' "$(<"$old_trap_marker")" \ 'post-cleanup/pre-output TERM reached the restored caller trap' } test_transaction_state_machine() { declare -F execute_transaction >/dev/null || { plain_fail 'full Slack KeePass transaction state machine is unavailable' return 1 } declare -F cleanup_transaction >/dev/null || fail 'cleanup_transaction is unavailable' declare -F defer_signal >/dev/null || fail 'defer_signal is unavailable' _swr_dirfd_helper() { if [[ "$1" == commit ]]; then return 75 fi if [[ "$1" == status ]]; then builtin printf '%s\n' verified-commit return 0 fi return 97 } local _swr_durable_status='' _swr_command() { command "$@"; } _swr_dirfd_commit _swr_durable_status /fixture/mount /fixture/work backup.kdbx || fail 'durable verified commit was overridden by lost helper exit status' _swr_command() { _swr_fake_command "$@"; } assert_eq verified-commit "$_swr_durable_status" 'durable verified status differs' pass_transaction_case _swr_prepare_transaction() { _swr_fake_prepare_transaction "$@"; } _swr_start_vault() { _swr_fake_start_transaction_vault "$@"; } _swr_refresh_sudo() { _swr_fake_refresh_sudo "$@"; } _swr_probe_rw() { _swr_fake_probe_transaction_rw "$@"; } _swr_mount_volume_command() { _swr_fake_mount_transaction_volume "$@"; } _swr_validate_mount() { _swr_fake_validate_transaction_mount "$@"; } _swr_dirfd_snapshot() { _swr_fake_dirfd_snapshot "$@"; } _swr_unmount_volume() { _swr_fake_unmount_transaction_volume "$@"; } _swr_stably_unmounted() { _swr_fake_transaction_stably_unmounted "$@"; } _swr_vault_request() { _swr_fake_vault_transaction_request "$@"; } _swr_confirm_token() { _swr_fake_confirm_transaction "$@"; } _swr_dirfd_commit() { _swr_fake_dirfd_commit "$@"; } _swr_dirfd_snapshot_current() { _swr_fake_dirfd_snapshot_current "$@"; } _swr_stop_vault() { _swr_fake_stop_transaction_vault "$@"; } _swr_audit_runtime_processes() { _swr_fake_audit_runtime_processes "$@"; } _swr_remove_work_root() { _swr_fake_remove_transaction_work_root "$@"; } local initial_order mutation_tail initial_order=$'validate-runtime\nstart-vault-and-retain-inputs\nsudo-refresh\nprobe-ro-safety\nmount-ro\nvalidate-ro-mount\nsnapshot\nunmount-ro\nclassify' run_transaction_case noop NOOP $'SLACK_KEEPASS_RECOVERY=NOOP\nWINDOWS_SSD_UNMOUNTED=PASS\nOFF_HOST_RECOVERY_SATISFIED=NO' assert_transaction_prefix "$initial_order" 'initial no-op order differs' # Production break caught: a known RO mount-command failure with stable # source absence is precommit failure, while response loss with a retained # or ambiguous source still requires manual recovery. Reconcile only once. run_transaction_case mount-ro-failure PRECOMMIT_FAILURE '' assert_eq \ $'validate-runtime\nstart-vault-and-retain-inputs\nsudo-refresh\nprobe-ro-safety\nmount-ro\nunmount-ro\nstop-vault\naudit-processes\nremove-work-root' \ "$(<"$transaction_log")" 'known RO mount failure cleanup trace differs' assert_eq 1 "$(/usr/bin/grep -Fc unmount-ro "$transaction_log")" \ 'known RO mount failure reconciliation count differs' ! /usr/bin/grep -Eq '^(snapshot|classify|probe-rw-safety|mount-rw|commit)$' "$transaction_log" || fail 'known RO mount failure reached a later transaction effect' run_transaction_case mount-ro-response-loss-unresolved-source MANUAL_RECOVERY_REQUIRED \ 'SLACK_KEEPASS_RECOVERY=MANUAL_RECOVERY_REQUIRED' assert_eq 1 "$(/usr/bin/grep -Fc unmount-ro "$transaction_log")" \ 'RO mount response-loss reconciliation count differs' ! /usr/bin/grep -Eq '^(snapshot|classify|probe-rw-safety|mount-rw|commit)$' "$transaction_log" || fail 'RO mount response loss reached a later transaction effect' local metadata_scenario for metadata_scenario in \ validate-ro-wrong-uid validate-ro-wrong-gid validate-ro-wrong-mode; do run_transaction_case "$metadata_scenario" PRECOMMIT_FAILURE '' assert_eq 1 "$(/usr/bin/grep -Fc unmount-ro "$transaction_log")" \ "$metadata_scenario reconciliation count differs" ! /usr/bin/grep -Eq '^(snapshot|classify|probe-rw-safety|mount-rw|commit)$' "$transaction_log" || fail "$metadata_scenario reached a later transaction effect" done run_transaction_case absent VERIFIED_COMMIT $'SLACK_KEEPASS_RECOVERY=COMMITTED\nKDBX_PRECHANGE_BACKUP=CREATED\nWINDOWS_SSD_UNMOUNTED=PASS\nOFF_HOST_RECOVERY_SATISFIED=NO' mutation_tail="$(/usr/bin/sed -n '/^classify$/,$p' "$transaction_log")" [[ "$mutation_tail" == $'classify\nbuild-add\nverify-candidate\nconfirm-write\nprobe-rw-safety\nmount-rw\nvalidate-rw-mount\ncommit\nsnapshot-current\nverify-committed-copy\nunmount-rw\nstop-vault\naudit-processes\nremove-work-root' ]] || fail "absent mutation order differs: ${mutation_tail//$'\n'/ -> }" run_transaction_case mismatch-no-update PRECOMMIT_FAILURE '' run_transaction_case mismatch-update VERIFIED_COMMIT $'SLACK_KEEPASS_RECOVERY=COMMITTED\nKDBX_PRECHANGE_BACKUP=CREATED\nWINDOWS_SSD_UNMOUNTED=PASS\nOFF_HOST_RECOVERY_SATISFIED=NO' mutation_tail="$(/usr/bin/sed -n '/^classify$/,$p' "$transaction_log")" [[ "$mutation_tail" == $'classify\nconfirm-update\nbuild-update\nverify-candidate\nconfirm-write\nprobe-rw-safety\nmount-rw\nvalidate-rw-mount\ncommit\nsnapshot-current\nverify-committed-copy\nunmount-rw\nstop-vault\naudit-processes\nremove-work-root' ]] || fail "mismatch mutation order differs: ${mutation_tail//$'\n'/ -> }" local scenario state expected for scenario in duplicate wrong-master retained-input-drift original-drift backup-collision backup-fsync; do run_transaction_case "$scenario" PRECOMMIT_FAILURE '' done run_transaction_case hup-before PRECOMMIT_FAILURE '' 129 run_transaction_case int-before PRECOMMIT_FAILURE '' 130 run_transaction_case term-before PRECOMMIT_FAILURE '' 143 run_transaction_case hup-noop PRECOMMIT_FAILURE '' 129 run_transaction_case term-rw-probe PRECOMMIT_FAILURE '' 143 assert_eq 0 "$transaction_commit_calls" 'pending TERM after RW probe reached commit' run_transaction_case int-rw-validate PRECOMMIT_FAILURE '' 130 assert_eq 0 "$transaction_commit_calls" 'pending INT after RW validation reached commit' run_transaction_case lost-after-verified VERIFIED_COMMIT $'SLACK_KEEPASS_RECOVERY=COMMITTED\nKDBX_PRECHANGE_BACKUP=CREATED\nWINDOWS_SSD_UNMOUNTED=PASS\nOFF_HOST_RECOVERY_SATISFIED=NO' for scenario in rename-failure post-rename final-verification lost-helper; do run_transaction_case "$scenario" COMMITTED_BUT_UNCERTAIN 'SLACK_KEEPASS_RECOVERY=MANUAL_RECOVERY_REQUIRED' done run_transaction_case hup-during COMMITTED_BUT_UNCERTAIN 'SLACK_KEEPASS_RECOVERY=MANUAL_RECOVERY_REQUIRED' 129 run_transaction_case int-during COMMITTED_BUT_UNCERTAIN 'SLACK_KEEPASS_RECOVERY=MANUAL_RECOVERY_REQUIRED' 130 run_transaction_case term-during COMMITTED_BUT_UNCERTAIN 'SLACK_KEEPASS_RECOVERY=MANUAL_RECOVERY_REQUIRED' 143 run_transaction_case hup-final-unmount VERIFIED_COMMIT '' 129 run_transaction_case term-cleanup VERIFIED_COMMIT '' 143 run_transaction_case term-post-cleanup VERIFIED_COMMIT '' 143 late_post_cleanup_signal_case local signal_event signal_failures=0 for signal_event in \ validate-runtime start-vault-and-retain-inputs sudo-refresh probe-ro-safety \ mount-ro validate-ro-mount snapshot unmount-ro classify build-add \ verify-candidate confirm-write probe-rw-safety mount-rw validate-rw-mount; do ( signal_boundary_case "$signal_event" TERM ) || { builtin printf 'SIGNAL RED: %s\n' "$signal_event" >&2 signal_failures=$((signal_failures + 1)) } done ( signal_boundary_case confirm-update INT ) || { builtin printf 'SIGNAL RED: %s\n' confirm-update >&2 signal_failures=$((signal_failures + 1)) } (( signal_failures == 0 )) || fail "$signal_failures signal boundaries failed" for scenario in unmount-ro unmount-rw unmount-ambiguous; do run_transaction_case "$scenario" MANUAL_RECOVERY_REQUIRED 'SLACK_KEEPASS_RECOVERY=MANUAL_RECOVERY_REQUIRED' local unmount_phase="${scenario#unmount-}" [[ "$unmount_phase" == ambiguous ]] && unmount_phase=ro assert_eq 1 "$(/usr/bin/grep -Fc "unmount-${unmount_phase}" "$transaction_log")" \ "$scenario retried an ambiguous unmount" done } run_worker() { local fixture_dir="$1" worker_token="$2" shift 2 /usr/bin/timeout --signal=TERM --kill-after=5s 30s \ /usr/bin/bash "$0" --worker "$worker_token" "$fixture_dir" "$@" } audit_fixture_pids() { local fixture_dir="$1" pid_file pid orphan_count=0 shopt -s nullglob for pid_file in "$fixture_dir"/pid.*; do pid="${pid_file##*.}" if kill -0 "$pid" 2>/dev/null; then orphan_count=$((orphan_count + 1)) fi done shopt -u nullglob printf '%s\n' "$orphan_count" } create_synthetic_kdbx() { local fixture_dir="$1" database socket_path server_pid attempt local fixture_master="fixture-$RANDOM-$RANDOM-$$" local fixture_webhook='https://hooks.' fixture_webhook+='slack.com/services/T01234567/B01234567/XXXXXXXXXXXXXXXXXXXXXXXX' runtime_fixture="$(mktemp -d "/run/user/${UID}/slack-webhook-recovery-bash.XXXXXX")" chmod 0700 -- "$runtime_fixture" database="$runtime_fixture/baseline.kdbx" socket_path="$runtime_fixture/vault.sock" { builtin printf '%s\n' "$fixture_master" builtin printf '%s\n' "$fixture_master" } | HOME=/dev/null XDG_CONFIG_HOME=/dev/null LC_ALL=C.UTF-8 PATH=/usr/bin:/bin \ /usr/bin/keepassxc-cli db-create -q -p "$database" \ >"$fixture_dir/db-create.stdout" 2>"$fixture_dir/db-create.stderr" || fail 'synthetic KeePass database creation failed' chmod 0600 -- "$database" builtin printf '%s' "$fixture_webhook" >"$runtime_fixture/input-webhook" chmod 0600 -- "$runtime_fixture/input-webhook" if grep -Fq -- "$fixture_master" \ "$fixture_dir/db-create.stdout" "$fixture_dir/db-create.stderr"; then fail 'synthetic master appeared in captured KeePassXC output' fi { builtin printf '%s\n' 'Synthetic Slack App' builtin printf '%s\n' "$fixture_master" } | /usr/bin/python3 -c ' import importlib.util import os import sys spec = importlib.util.spec_from_file_location("swr_vault", sys.argv[1]) if spec is None or spec.loader is None: raise SystemExit(2) module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) output_fd = os.open(os.devnull, os.O_WRONLY | os.O_CLOEXEC) try: module.serve_private_socket( sys.argv[2], sys.argv[3], input_fd=0, output_fd=output_fd, accept_timeout=10.0, io_timeout=10.0, child_timeout=20.0, ) finally: os.close(output_fd) ' "$ROOT/scripts/libexec/slack-webhook-recovery-vault.py" \ "$runtime_fixture" "$runtime_fixture/input-webhook" \ >"$fixture_dir/vault.stdout" 2>"$fixture_dir/vault.stderr" & server_pid=$! builtin printf '' >"$fixture_dir/pid.$server_pid" for (( attempt = 0; attempt < 100; attempt++ )); do [[ -S "$socket_path" ]] && break kill -0 "$server_pid" 2>/dev/null || fail 'imported vault server exited early' /usr/bin/sleep 0.05 done [[ -S "$socket_path" ]] || fail 'imported vault socket did not appear' [[ "$(stat -c '%a' "$socket_path")" == 600 ]] || fail 'vault socket mode differs' if grep -Fq -- "$fixture_master" "/proc/$server_pid/cmdline" \ "/proc/$server_pid/environ" "$fixture_dir/vault.stdout" \ "$fixture_dir/vault.stderr"; then fail 'synthetic master escaped the vault process boundary' fi if grep -Fq -- "$fixture_webhook" "/proc/$server_pid/cmdline" \ "/proc/$server_pid/environ" "$fixture_dir/vault.stdout" \ "$fixture_dir/vault.stderr"; then fail 'synthetic webhook escaped the vault process boundary' fi local _swr_reply='' _swr_vault_request _swr_reply "$socket_path" PREPARE || fail 'vault PREPARE request failed' assert_eq absent "$_swr_reply" 'absent database classification differs' _swr_vault_request _swr_reply "$socket_path" 'BUILD ADD' || fail 'vault BUILD ADD request failed' assert_eq candidate-ready "$_swr_reply" 'candidate response differs' _swr_vault_request _swr_reply "$socket_path" VERIFY_CANDIDATE || fail 'vault VERIFY_CANDIDATE request failed' assert_eq verified "$_swr_reply" 'candidate verification response differs' _swr_vault_request _swr_reply "$socket_path" \ "VERIFY_COMMITTED $runtime_fixture/candidate.kdbx" || fail 'vault VERIFY_COMMITTED request failed' assert_eq verified "$_swr_reply" 'candidate verification response differs' _swr_stop_vault "$socket_path" "$server_pid" || fail 'vault shutdown failed' [[ ! -S "$socket_path" ]] || fail 'vault socket remained after shutdown' unset fixture_master unset fixture_webhook } cleanup_runtime_fixture() { if [[ "$runtime_fixture" == "/run/user/${UID}/slack-webhook-recovery-bash."* ]]; then rm -rf -- "$runtime_fixture" fi if [[ "$owned_work_fixture" == /run/user/1000/platform-slack-keepass.* && -d "$owned_work_fixture" && ! -L "$owned_work_fixture" && -O "$owned_work_fixture" ]]; then /usr/bin/rmdir -- "$owned_work_fixture" 2>/dev/null || true fi } cleanup_fixture() { cleanup_runtime_fixture [[ "$fixture_dir" == /tmp/slack-webhook-recovery-test.* || "$fixture_dir" == "${TMPDIR:-/tmp}"/slack-webhook-recovery-test.* ]] || return 0 rm -rf -- "$fixture_dir" } worker_main() { local worker_token="$1" fixture_dir="$2" trap cleanup_runtime_fixture EXIT shift 2 local expected_token_file="$fixture_dir/worker-token" [[ -f "$expected_token_file" ]] || fail 'worker token file is absent' [[ "$( <"$expected_token_file" )" == "$worker_token" ]] || fail 'worker token mismatch' [[ $# -eq 0 ]] || fail 'focused suite worker accepts no public argv' # The production change this catches is widening the closed CLI boundary or # contacting any external secret/mount path on the default invocation. [[ -x "$PROD" ]] || fail 'production Slack KeePass recovery helper is absent' local output relative_output output="$(/usr/bin/env -i PATH=/definitely-invalid /usr/bin/bash "$PROD")" || fail 'default invocation failed' assert_eq \ $'SLACK_KEEPASS_RECOVERY_MODE=DRY_RUN\nWINDOWS_SSD_UUID=4EA0196C0C5FA27E\nKDBX_RELATIVE_PATH=HyeonworksRecovery/vault/hyeonworks-recovery.kdbx\nMUTATION=NOT_REQUESTED\nOFF_HOST_RECOVERY_SATISFIED=NO' \ "$output" \ 'default output differs' relative_output="$( cd -- "$ROOT" && /usr/bin/env -i PATH=/definitely-invalid /usr/bin/bash \ scripts/bootstrap/backup-slack-webhook-recovery.sh )" || fail 'repository-relative default invocation failed' assert_eq "$output" "$relative_output" 'repository-relative default output differs' /usr/bin/env -i PATH=/usr/bin:/bin /usr/bin/bash "$PROD" --unknown >/dev/null 2>&1 && fail 'unknown argv was accepted' /usr/bin/env -i PATH=/usr/bin:/bin /usr/bin/bash "$PROD" --execute --execute >/dev/null 2>&1 && fail 'duplicate execute argv was accepted' /usr/bin/env -i PATH=/usr/bin:/bin /usr/bin/bash "$PROD" --execute --slack-webhook-file >/dev/null 2>&1 && fail 'missing webhook path was accepted' /usr/bin/env -i PATH=/usr/bin:/bin /usr/bin/bash "$PROD" --execute --slack-webhook-file relative/path >/dev/null 2>&1 && fail 'relative webhook path was accepted' /usr/bin/env -i PATH=/usr/bin:/bin /usr/bin/bash "$PROD" --slack-webhook-file /tmp/placeholder --execute >/dev/null 2>&1 && fail 'reordered argv was accepted' /usr/bin/env -i PATH=/usr/bin:/bin CDPATH=/tmp /usr/bin/bash "$PROD" >/dev/null 2>&1 && fail 'CDPATH override was accepted' /usr/bin/env -i PATH=/usr/bin:/bin BASH_ENV=/dev/null /usr/bin/bash "$PROD" >/dev/null 2>&1 && fail 'BASH_ENV override was accepted' /usr/bin/env -i PATH=/usr/bin:/bin ENV=/dev/null /usr/bin/bash "$PROD" >/dev/null 2>&1 && fail 'ENV override was accepted' /usr/bin/env -i PATH=/usr/bin:/bin 'BASH_FUNC_printf%%=() { :; }' /usr/bin/bash "$PROD" >/dev/null 2>&1 && fail 'imported command override was accepted' /usr/bin/env -i PATH=/usr/bin:/bin SHELLOPTS=braceexpand:hashall /usr/bin/bash "$PROD" >/dev/null 2>&1 && fail 'inherited SHELLOPTS was accepted' /usr/bin/env -i PATH=/usr/bin:/bin /usr/bin/bash "$PROD" --execute --slack-webhook-file /tmp/placeholder >/dev/null 2>&1 && fail 'execute mode without tty was accepted' # shellcheck source=/dev/null SWR_REPOSITORY_ROOT="$ROOT" source "$LIB" production_runtime_root_definition="$(declare -f _swr_runtime_root)" _swr_command() { _swr_fake_command "$@"; } _swr_runtime_root() { _swr_fake_runtime_root "$@"; } _swr_volume_action() { _swr_fake_volume_action "$@"; } local required_boundary for required_boundary in \ _swr_load_recovery_contract _swr_resolve_device _swr_require_unmounted \ _swr_probe_rw _swr_mount_volume _swr_validate_mount _swr_unmount_volume \ _swr_create_mountpoint _swr_require_mountpoint_unused \ _swr_run_volume_cycle _swr_open_recovery_boundary; do declare -F "$required_boundary" >/dev/null || fail 'exact Windows SSD mount boundary is unavailable' done _swr_initial_guard 0 '' '' '' "$PROD" && fail 'root EUID guard was accepted' fake_runtime_root="$fixture_dir/runtime-root" fake_log="$fixture_dir/fake-command.log" fake_mount_state="$fixture_dir/fake-mount-state" fake_probe_status="$fixture_dir/fake-probe-status" fake_mount_status="$fixture_dir/fake-mount-status" fake_umount_status="$fixture_dir/fake-umount-status" fake_umount_after="$fixture_dir/fake-umount-after" fake_sudo_status="$fixture_dir/fake-sudo-status" fake_source_query_count="$fixture_dir/fake-source-query-count" fake_action_count="$fixture_dir/fake-action-count" fake_mount_uncertain="$fixture_dir/fake-mount-uncertain" fake_case_file="$fixture_dir/fake-case" fake_mountpoint="$fake_runtime_root/not-created" fake_action=noop mkdir -m 0700 -- "$fake_runtime_root" _swr_command /fixture/fake-only-sentinel || fail 'fixed command leaf was not intercepted after production source' assert_log_line '/fixture/fake-only-sentinel' 'fake-only command sentinel was not logged' pass_boundary_case owned_work_fixture="$(/usr/bin/mktemp -d --tmpdir=/run/user/1000 platform-slack-keepass.XXXXXXXX)" /usr/bin/chmod 0700 -- "$owned_work_fixture" _swr_work_root_is_safe "$owned_work_fixture" || fail 'owned private tmpfs work root was rejected' /usr/bin/rmdir -- "$owned_work_fixture" owned_work_fixture='' pass_transaction_case test_contract_and_device_boundary test_probe_mount_and_validation_boundary test_unmount_and_cycle_boundary test_full_fake_boundary_ordering test_review_fix_round_one test_review_fix_round_two test_task5_fix_round_one_boundaries test_task5_fix_round_four_inventory_boundaries test_vault_readiness_failure_boundaries test_pending_signal_after_readiness_prevents_publication test_start_vault_waits_for_delayed_operator_input create_synthetic_kdbx "$fixture_dir" declare -F _swr_start_vault >/dev/null || fail 'KeePass database classifier is unavailable' transaction_log="$fixture_dir/transaction.log" test_transaction_state_machine builtin printf 'PASS: %s exact device/probe/mount boundary cases; %s transaction cases; fake-only sentinel=pass; real privileged calls=0\n' \ "$boundary_cases" "$transaction_cases" } supervisor_main() { (( $# == 0 )) || fail 'focused suite accepts no public argv' fixture_dir="$(mktemp -d "${TMPDIR:-/tmp}/slack-webhook-recovery-test.XXXXXX")" trap cleanup_fixture EXIT local worker_token printf -v worker_token 'worker-%(%s)T-%s-%s' -1 "$$" "$RANDOM" printf '%s' "$worker_token" >"$fixture_dir/worker-token" local stdout_file="$fixture_dir/stdout" stderr_file="$fixture_dir/stderr" local started_at finished_at rc orphan_count printf -v started_at '%(%s)T' -1 set +e run_worker "$fixture_dir" "$worker_token" >"$stdout_file" 2>"$stderr_file" rc=$? set -e printf -v finished_at '%(%s)T' -1 orphan_count="$(audit_fixture_pids "$fixture_dir")" if [[ "$orphan_count" != 0 ]]; then cat "$stderr_file" >&2 fail 'worker left fixture-owned processes behind' fi (( finished_at - started_at <= 30 )) || fail 'worker exceeded supervisor wall bound' cat "$stdout_file" if (( rc == 0 )); then cleanup_fixture trap - EXIT return 0 fi cat "$stderr_file" >&2 cleanup_fixture trap - EXIT return "$rc" } if [[ "${1-}" == --worker ]]; then [[ "${SWR_TEST_WORKER_TOKEN:-}" == '' ]] || fail 'worker token must not arrive from environment' (( $# >= 3 )) || fail 'worker dispatch is incomplete' worker_main "$2" "$3" "${@:4}" exit 0 fi supervisor_main "$@"