#!/usr/bin/env bash # Source-only strict A1 recovery payload verifier. readonly K3SLRA1_MANIFEST_MAX_BYTES=65536 readonly K3SLRA1_PATH_MAX_BYTES=512 readonly K3SLRA1_MOUNT_RECORD_MAX_BYTES=4096 readonly K3SLRA1_TARGET_COUNT=80 readonly K3SLRA1_TARGET_BYTES=22857829 readonly K3SLRA1_METADATA_FORMAT='%d:%i|%h|%s|%y|%F|%u:%g|%a' readonly K3SLRA1_CANONICAL_DATABASE='./datastore/state.db' readonly K3SLRA1_LEGACY_DATABASE='./rootfs/var/lib/rancher/k3s/server/db/state.db' readonly K3SLRA1_MAIN_MAPPER='/dev/mapper/k3s-recovery' readonly K3SLRA1_PROOF_MAPPER='/dev/mapper/k3s-recovery-proof' readonly K3SLRA1_MAIN_MAPPING_NAME=k3s-recovery readonly K3SLRA1_PROOF_MAPPING_NAME=k3s-recovery-proof readonly K3SLRA1_SQLITE_QUERY='PRAGMA query_only=ON; PRAGMA quick_check;' _k3slra1_command() { "$@" } _k3slra1_output_name_is_safe() { local output_name="${1-}" (( $# == 1 )) || return 1 [[ "$output_name" =~ ^[A-Za-z_][A-Za-z0-9_]*$ ]] || return 1 [[ "$output_name" != _k3slra1_* ]] } _k3slra1_metadata() { local path="${1-}" output_name="${2-}" line='' (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != path ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != line ]] || return 1 _k3slra1_packet_line metadata "$path" line || return 1 printf -v "$output_name" '%s' "$line" } _k3slra1_canonical_path() { local path="${1-}" output_name="${2-}" line='' (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != path ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != line ]] || return 1 _k3slra1_packet_line readlink "$path" line || return 1 printf -v "$output_name" '%s' "$line" } _k3slra1_metadata_packet() { local path="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/stat --format="$K3SLRA1_METADATA_FORMAT" -- "$path" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_fd_metadata_packet() { local path="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/stat --dereference --format="$K3SLRA1_METADATA_FORMAT" -- "$path" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_mapper_stat_packet() { local mapper="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/stat --format='%F|%Hr:%Lr' -- "$mapper" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_size_stat_packet() { local path="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/stat --format='%s' -- "$path" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_wc_packet() { local path="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/wc -c -- "$path" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_od_packet() { local path="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/od -An -v -tx1 -- "$path" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_sha256_packet() { local path="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/sha256sum -- "$path" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_findmnt_packet() { local mount_root="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/findmnt --noheadings --raw --mountpoint "$mount_root" --output SOURCE,TARGET,FSTYPE,VFS-OPTIONS,FS-OPTIONS,MAJ:MIN 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_readlink_packet() { local mapper="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/readlink --canonicalize-existing -- "$mapper" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_lsblk_packet() { local mapper="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/lsblk --noheadings --nodeps --raw --output MAJ:MIN -- "$mapper" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_blockdev_packet() { local mapper="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/sbin/blockdev --getro "$mapper" 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf '\0RC=%s\0' "$rc" } _k3slra1_stderr_marker() { local chunk='' read_rc=0 if IFS= read -r -d '' -n 1 chunk; then read_rc=0 else read_rc=$? fi if (( read_rc == 0 )); then printf '\0STDERR\0' while IFS= read -r -d '' -n 4096 chunk; do : done else if [[ -n "$chunk" ]]; then printf '\0STDERR\0' fi fi } _k3slra1_packet_value() { local producer="${1-}" argument="${2-}" output_name="${3-}" local -a records=() (( $# == 3 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != producer ]] || return 1 [[ "$output_name" != argument ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != records ]] || return 1 case "$producer" in findmnt) mapfile -d '' -t records < <(_k3slra1_findmnt_packet "$argument") ;; metadata) mapfile -d '' -t records < <(_k3slra1_metadata_packet "$argument") ;; fd-metadata) mapfile -d '' -t records < <(_k3slra1_fd_metadata_packet "$argument") ;; mapper-stat) mapfile -d '' -t records < <(_k3slra1_mapper_stat_packet "$argument") ;; size-stat) mapfile -d '' -t records < <(_k3slra1_size_stat_packet "$argument") ;; wc) mapfile -d '' -t records < <(_k3slra1_wc_packet "$argument") ;; od) mapfile -d '' -t records < <(_k3slra1_od_packet "$argument") ;; sha256) mapfile -d '' -t records < <(_k3slra1_sha256_packet "$argument") ;; readlink) mapfile -d '' -t records < <(_k3slra1_readlink_packet "$argument") ;; lsblk) mapfile -d '' -t records < <(_k3slra1_lsblk_packet "$argument") ;; blockdev) mapfile -d '' -t records < <(_k3slra1_blockdev_packet "$argument") ;; *) return 1 ;; esac (( ${#records[@]} == 2 )) || return 1 [[ "${records[1]}" == RC=0 ]] || return 1 printf -v "$output_name" '%s' "${records[0]}" } _k3slra1_packet_line() { local producer="${1-}" argument="${2-}" output_name="${3-}" value='' (( $# == 3 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 case "$output_name" in producer|argument|output_name|value) return 1 ;; esac _k3slra1_packet_value "$producer" "$argument" value || return 1 [[ "$value" == *$'\n' ]] || return 1 [[ "$value" != *$'\r'* ]] || return 1 value="${value%$'\n'}" [[ -n "$value" ]] || return 1 [[ "$value" != *$'\n'* ]] || return 1 printf -v "$output_name" '%s' "$value" } _k3slra1_option_has() { local options="${1-}" wanted="${2-}" option local -a option_list=() (( $# == 2 )) || return 1 IFS=, read -r -a option_list <<<"$options" for option in "${option_list[@]}"; do [[ "$option" == "$wanted" ]] && return 0 done return 1 } _k3slra1_expected_mapper() { local role="${1-}" output_name="${2-}" value='' (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != role ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != value ]] || return 1 case "$role" in proof) value="$K3SLRA1_PROOF_MAPPER" ;; original-baseline|original-final) value="$K3SLRA1_MAIN_MAPPER" ;; *) return 1 ;; esac printf -v "$output_name" '%s' "$value" } _k3slra1_capture_mount_mapping_evidence() { local mount_root="${1-}" role="${2-}" output_name="${3-}" local expected_mapper='' mount_record='' mount_line='' source='' target='' fstype='' local vfs_options='' fs_options='' mount_major_minor='' extra='' local source_canonical='' canonical_mapper='' mapper_major_minor='' mapper_readonly='' mapper_stat='' (( $# == 3 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 case "$output_name" in mount_root|role|output_name|expected_mapper|mount_record|mount_line|source|target|fstype|vfs_options|fs_options|mount_major_minor|extra|source_canonical|canonical_mapper|mapper_major_minor|mapper_readonly|mapper_stat) return 1 ;; esac _k3slra1_expected_mapper "$role" expected_mapper || return 1 _k3slra1_packet_value findmnt "$mount_root" mount_record || return 1 (( ${#mount_record} >= 1 )) || return 1 (( ${#mount_record} <= K3SLRA1_MOUNT_RECORD_MAX_BYTES )) || return 1 [[ "$mount_record" == *$'\n' ]] || return 1 [[ "$mount_record" != *$'\r'* ]] || return 1 mount_line="${mount_record%$'\n'}" [[ -n "$mount_line" ]] || return 1 [[ "$mount_line" != *$'\n'* ]] || return 1 [[ "$mount_line" =~ ^([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)[[:space:]]+([^[:space:]]+)$ ]] || return 1 source="${BASH_REMATCH[1]}" target="${BASH_REMATCH[2]}" fstype="${BASH_REMATCH[3]}" vfs_options="${BASH_REMATCH[4]}" fs_options="${BASH_REMATCH[5]}" mount_major_minor="${BASH_REMATCH[6]}" [[ -n "$source" ]] || return 1 [[ -n "$target" ]] || return 1 [[ -n "$fstype" ]] || return 1 [[ -n "$vfs_options" ]] || return 1 [[ -n "$fs_options" ]] || return 1 [[ -n "$mount_major_minor" ]] || return 1 [[ -z "$extra" ]] || return 1 [[ "$target" == "$mount_root" ]] || return 1 [[ "$fstype" == ext4 ]] || return 1 _k3slra1_option_has "$vfs_options" ro || return 1 _k3slra1_option_has "$vfs_options" nodev || return 1 _k3slra1_option_has "$vfs_options" nosuid || return 1 _k3slra1_option_has "$vfs_options" noexec || return 1 case ",${vfs_options}," in *,rw,*|*,dev,*|*,suid,*|*,exec,*) return 1 ;; esac _k3slra1_option_has "$fs_options" noload || return 1 _k3slra1_packet_line readlink "$source" source_canonical || return 1 _k3slra1_packet_line readlink "$expected_mapper" canonical_mapper || return 1 [[ "$canonical_mapper" == "$source_canonical" ]] || return 1 [[ "$canonical_mapper" =~ ^/dev/dm-[0-9]+$ ]] || return 1 _k3slra1_packet_line mapper-stat "$canonical_mapper" mapper_stat || return 1 [[ "$mapper_stat" == "block special file|${mount_major_minor}" ]] || return 1 _k3slra1_packet_line lsblk "$canonical_mapper" mapper_major_minor || return 1 [[ "$mapper_major_minor" == "$mount_major_minor" ]] || return 1 _k3slra1_packet_value blockdev "$canonical_mapper" mapper_readonly || return 1 [[ "$mapper_readonly" == $'1\n' ]] || return 1 printf -v "$output_name" '%s' "${mount_record}|${canonical_mapper}|${mapper_major_minor}|${mapper_readonly}" } _k3slra1_output_names_are_distinct() { local name seen_name local -A seen=() (( $# >= 1 )) || return 1 for name in "$@"; do _k3slra1_output_name_is_safe "$name" || return 1 [[ "${seen[$name]+set}" != set ]] || return 1 printf -v 'seen[$name]' '%s' 1 done } _k3slra1_output_names_avoid() { local output_count="${1-}" output_index=0 output_name forbidden_name local -a output_names=() (( $# >= 2 )) || return 1 [[ "$output_count" =~ ^[1-9][0-9]*$ ]] || return 1 shift (( $# >= 10#$output_count + 1 )) || return 1 for (( output_index = 0; output_index < 10#$output_count; output_index += 1 )); do output_names+=("${1-}") shift done for forbidden_name in "$@"; do for output_name in "${output_names[@]}"; do [[ "$output_name" != "$forbidden_name" ]] || return 1 done done } _k3slra1_metadata_fields() { local path="${1-}" out_identity="${2-}" out_nlink="${3-}" out_size="${4-}" local out_mtime="${5-}" out_type="${6-}" out_owner="${7-}" out_mode="${8-}" local metadata='' _k3slra1_type_value='' (( $# == 8 )) || return 1 _k3slra1_output_names_are_distinct "$out_identity" "$out_nlink" "$out_size" "$out_mtime" "$out_type" "$out_owner" "$out_mode" || return 1 case "$out_identity|$out_nlink|$out_size|$out_mtime|$out_type|$out_owner|$out_mode" in *'|path|'*|path\|*|*\|path|*'|out_identity|'*|out_identity\|*|*\|out_identity|*'|out_nlink|'*|out_nlink\|*|*\|out_nlink|*'|out_size|'*|out_size\|*|*\|out_size|*'|out_mtime|'*|out_mtime\|*|*\|out_mtime|*'|out_type|'*|out_type\|*|*\|out_type|*'|out_owner|'*|out_owner\|*|*\|out_owner|*'|out_mode|'*|out_mode\|*|*\|out_mode|*'|metadata|'*|metadata\|*|*\|metadata) return 1 ;; esac _k3slra1_metadata "$path" metadata || return 1 [[ "$metadata" =~ ^([0-9]+:[0-9]+)\|([0-9]+)\|([0-9]+)\|([^|]+)\|(directory|regular[[:space:]]file|regular[[:space:]]empty[[:space:]]file|symbolic[[:space:]]link)\|([0-9]+:[0-9]+)\|([0-9]+)$ ]] || return 1 _k3slra1_type_value="${BASH_REMATCH[5]}" if [[ "$_k3slra1_type_value" == 'regular empty file' ]]; then printf -v _k3slra1_type_value '%s' 'regular file' fi printf -v "$out_identity" '%s' "${BASH_REMATCH[1]}" printf -v "$out_nlink" '%s' "${BASH_REMATCH[2]}" printf -v "$out_size" '%s' "${BASH_REMATCH[3]}" printf -v "$out_mtime" '%s' "${BASH_REMATCH[4]}" printf -v "$out_type" '%s' "$_k3slra1_type_value" printf -v "$out_owner" '%s' "${BASH_REMATCH[6]}" printf -v "$out_mode" '%s' "${BASH_REMATCH[7]}" } _k3slra1_fd_metadata_fields() { local path="${1-}" out_identity="${2-}" out_nlink="${3-}" out_size="${4-}" local out_mtime="${5-}" out_type="${6-}" out_owner="${7-}" out_mode="${8-}" local metadata='' _k3slra1_type_value='' (( $# == 8 )) || return 1 _k3slra1_output_names_are_distinct "$out_identity" "$out_nlink" "$out_size" "$out_mtime" "$out_type" "$out_owner" "$out_mode" || return 1 case "$out_identity|$out_nlink|$out_size|$out_mtime|$out_type|$out_owner|$out_mode" in *'|path|'*|path\|*|*\|path|*'|out_identity|'*|out_identity\|*|*\|out_identity|*'|out_nlink|'*|out_nlink\|*|*\|out_nlink|*'|out_size|'*|out_size\|*|*\|out_size|*'|out_mtime|'*|out_mtime\|*|*\|out_mtime|*'|out_type|'*|out_type\|*|*\|out_type|*'|out_owner|'*|out_owner\|*|*\|out_owner|*'|out_mode|'*|out_mode\|*|*\|out_mode|*'|metadata|'*|metadata\|*|*\|metadata) return 1 ;; esac _k3slra1_packet_line fd-metadata "$path" metadata || return 1 [[ "$metadata" =~ ^([0-9]+:[0-9]+)\|([0-9]+)\|([0-9]+)\|([^|]+)\|(directory|regular[[:space:]]file|regular[[:space:]]empty[[:space:]]file|symbolic[[:space:]]link)\|([0-9]+:[0-9]+)\|([0-9]+)$ ]] || return 1 _k3slra1_type_value="${BASH_REMATCH[5]}" if [[ "$_k3slra1_type_value" == 'regular empty file' ]]; then printf -v _k3slra1_type_value '%s' 'regular file' fi printf -v "$out_identity" '%s' "${BASH_REMATCH[1]}" printf -v "$out_nlink" '%s' "${BASH_REMATCH[2]}" printf -v "$out_size" '%s' "${BASH_REMATCH[3]}" printf -v "$out_mtime" '%s' "${BASH_REMATCH[4]}" printf -v "$out_type" '%s' "$_k3slra1_type_value" printf -v "$out_owner" '%s' "${BASH_REMATCH[6]}" printf -v "$out_mode" '%s' "${BASH_REMATCH[7]}" } _k3slra1_find_mount_children_packet() { local mount_root="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/find "$mount_root" -mindepth 1 -maxdepth 1 -print0 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf 'RC=%s\0' "$rc" } _k3slra1_find_regular_packet() { local pre_root="${1-}" rc=0 (( $# == 1 )) || return 1 if _k3slra1_command /usr/bin/find "$pre_root" -xdev -type f -print0 2> >(_k3slra1_stderr_marker); then rc=0 else rc=$? fi printf 'RC=%s\0' "$rc" } _k3slra1_select_pre_bundle() { local mount_root="${1-}" output_name="${2-}" entry base _k3slra1_selected_value='' local canonical_mount='' canonical_bundle='' canonical_pre='' canonical_manifest='' local mount_identity='' mount_nlink='' mount_size='' mount_mtime='' mount_type='' mount_owner='' mount_mode='' local bundle_identity='' bundle_nlink='' bundle_size='' bundle_mtime='' bundle_type='' bundle_owner='' bundle_mode='' local pre_identity='' pre_nlink='' pre_size='' pre_mtime='' pre_type='' pre_owner='' pre_mode='' local manifest_identity='' manifest_nlink='' manifest_size='' manifest_mtime='' manifest_type='' manifest_owner='' manifest_mode='' local pre_root='' manifest='' match_count=0 last_index=0 local -a entries=() (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 _k3slra1_output_names_avoid 1 "$output_name" mount_root output_name entry base canonical_mount canonical_bundle canonical_pre canonical_manifest mount_identity mount_nlink mount_size mount_mtime mount_type mount_owner mount_mode bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode manifest_identity manifest_nlink manifest_size manifest_mtime manifest_type manifest_owner manifest_mode pre_root manifest match_count last_index entries || return 1 mapfile -d '' -t entries < <(_k3slra1_find_mount_children_packet "$mount_root") (( ${#entries[@]} >= 1 )) || return 1 (( last_index = ${#entries[@]} - 1 )) [[ "${entries[$last_index]}" == RC=0 ]] || return 1 unset 'entries[last_index]' for entry in "${entries[@]}"; do [[ -n "$entry" ]] || return 1 [[ "$entry" != STDERR ]] || return 1 base="${entry##*/}" if [[ "$base" =~ ^k3s-secrets-encryption-[0-9]{8}T[0-9]{6}Z$ ]]; then (( match_count += 1 )) _k3slra1_selected_value="$entry" fi done (( match_count == 1 )) || return 1 pre_root="${_k3slra1_selected_value}/pre" manifest="${pre_root}/verification.manifest" _k3slra1_canonical_path "$mount_root" canonical_mount || return 1 _k3slra1_canonical_path "$_k3slra1_selected_value" canonical_bundle || return 1 _k3slra1_canonical_path "$pre_root" canonical_pre || return 1 _k3slra1_canonical_path "$manifest" canonical_manifest || return 1 [[ "$canonical_mount" == "$mount_root" ]] || return 1 [[ "$canonical_bundle" == "$_k3slra1_selected_value" ]] || return 1 [[ "$canonical_pre" == "$pre_root" ]] || return 1 [[ "$canonical_manifest" == "$manifest" ]] || return 1 _k3slra1_metadata_fields "$mount_root" mount_identity mount_nlink mount_size mount_mtime mount_type mount_owner mount_mode || return 1 _k3slra1_metadata_fields "$_k3slra1_selected_value" bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode || return 1 _k3slra1_metadata_fields "$pre_root" pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode || return 1 _k3slra1_metadata_fields "$manifest" manifest_identity manifest_nlink manifest_size manifest_mtime manifest_type manifest_owner manifest_mode || return 1 [[ "$mount_type" == directory ]] || return 1 [[ "$bundle_type" == directory ]] || return 1 [[ "$pre_type" == directory ]] || return 1 [[ "$manifest_type" == 'regular file' ]] || return 1 [[ "$bundle_owner" == 0:0 ]] || return 1 [[ "$pre_owner" == 0:0 ]] || return 1 [[ "$manifest_owner" == 0:0 ]] || return 1 [[ "$bundle_mode" == 700 ]] || return 1 [[ "$pre_mode" == 700 ]] || return 1 [[ "$manifest_mode" == 600 ]] || return 1 [[ "$manifest_nlink" == 1 ]] || return 1 [[ "${bundle_identity%%:*}" == "${mount_identity%%:*}" ]] || return 1 [[ "${pre_identity%%:*}" == "${mount_identity%%:*}" ]] || return 1 [[ "${manifest_identity%%:*}" == "${mount_identity%%:*}" ]] || return 1 printf -v "$output_name" '%s' "$_k3slra1_selected_value" } _k3slra1_capture_manifest_hex() { local manifest="${1-}" output_name="${2-}" stat_size='' byte_count='' od_output='' hex='' (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != manifest ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != size ]] || return 1 [[ "$output_name" != stat_size ]] || return 1 [[ "$output_name" != byte_count ]] || return 1 [[ "$output_name" != od_output ]] || return 1 [[ "$output_name" != hex ]] || return 1 _k3slra1_packet_line size-stat "$manifest" stat_size || return 1 [[ "$stat_size" =~ ^[0-9]+$ ]] || return 1 (( 10#$stat_size >= 1 )) || return 1 (( 10#$stat_size <= K3SLRA1_MANIFEST_MAX_BYTES )) || return 1 _k3slra1_packet_line wc "$manifest" byte_count || return 1 [[ "$byte_count" == *"$manifest" ]] || return 1 byte_count="${byte_count%"$manifest"}" [[ "$byte_count" == *[[:space:]] ]] || return 1 byte_count="${byte_count//[[:space:]]/}" [[ "$byte_count" == "$stat_size" ]] || return 1 _k3slra1_packet_value od "$manifest" od_output || return 1 [[ "$od_output" == *$'\n' ]] || return 1 [[ "$od_output" != *$'\r'* ]] || return 1 od_output="${od_output%$'\n'}" [[ -n "$od_output" ]] || return 1 [[ "$od_output" != *$'\n' ]] || return 1 [[ "$od_output" != *$'\n\n'* ]] || return 1 hex="${od_output//[[:space:]]/}" [[ "$hex" =~ ^[0-9a-f]+$ ]] || return 1 (( ${#hex} == 10#$stat_size * 2 )) || return 1 [[ " $od_output " != *[[:space:]]00[[:space:]]* ]] || return 1 [[ " $od_output " != *[[:space:]]0d[[:space:]]* ]] || return 1 [[ "${hex: -2}" == 0a ]] || return 1 printf -v "$output_name" '%s' "$hex" } _k3slra1_verify_payload() { # Internal-only: the proof orchestrator supplies a reviewed helper staged in # its root-owned runtime tmpfs before this privileged dispatch boundary. local mount_root="${1-}" role="${2-}" capture_root="${3-}" local helper='' (( $# == 3 )) || return 1 case "$role" in original-baseline|proof|original-final) ;; *) return 1 ;; esac helper="${capture_root}/libexec/k3s-local-recovery-a1-check.sh" _k3slra1_command /usr/bin/sudo --non-interactive -- /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LC_ALL=C /usr/bin/bash --noprofile --norc -- "$helper" "$mount_root" "$role" "$capture_root" >/dev/null 2>&1 } _k3slra1_verify_payload_root() { local mount_root="${1-}" role="${2-}" capture_root="${3-}" local _bundle='' _layout='' _count_before='' _bytes_before='' _snapshot_before='' local _count_after='' _bytes_after='' _snapshot_after='' local _mount_before='' _mount_sqlite='' _mount_after='' _sqlite_rc=0 (( $# == 3 )) || return 1 case "$role" in original-baseline|proof|original-final) ;; *) return 1 ;; esac _k3slra1_capture_mount_mapping_evidence "$mount_root" "$role" _mount_before || return 1 _k3slra1_select_pre_bundle "$mount_root" _bundle || return 1 _k3slra1_analyze_manifest "$_bundle" _count_before _bytes_before _snapshot_before || return 1 [[ "$_count_before" == "$K3SLRA1_TARGET_COUNT" ]] || return 1 [[ "$_bytes_before" == "$K3SLRA1_TARGET_BYTES" ]] || return 1 _k3slra1_select_sqlite_layout_from_snapshot "$_bundle" "$_snapshot_before" _layout || return 1 _k3slra1_capture_mount_mapping_evidence "$mount_root" "$role" _mount_sqlite || return 1 [[ "$_mount_sqlite" == "$_mount_before" ]] || return 1 if _k3slra1_sqlite_quick_check "$_bundle" "$_layout" "$capture_root"; then _sqlite_rc=0 else _sqlite_rc=$? fi case "$_sqlite_rc" in 0) ;; 130|143) return "$_sqlite_rc" ;; *) return 1 ;; esac _k3slra1_analyze_manifest "$_bundle" _count_after _bytes_after _snapshot_after || return 1 [[ "$_count_after" == "$_count_before" ]] || return 1 [[ "$_bytes_after" == "$_bytes_before" ]] || return 1 [[ "$_snapshot_after" == "$_snapshot_before" ]] || return 1 _k3slra1_capture_mount_mapping_evidence "$mount_root" "$role" _mount_after || return 1 [[ "$_mount_after" == "$_mount_before" ]] } _k3slra1_sha256_record() { local path="${1-}" output_name="${2-}" line='' (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != path ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != value ]] || return 1 [[ "$output_name" != line ]] || return 1 _k3slra1_packet_line sha256 "$path" line || return 1 printf -v "$output_name" '%s' "$line" } _k3slra1_analyze_manifest() { local bundle="${1-}" out_count="${2-}" out_bytes="${3-}" out_snapshot="${4-}" local mount_root='' _selected_value='' pre_root='' manifest='' manifest_hex_before='' manifest_hex_after='' local bundle_identity='' bundle_nlink='' bundle_size='' bundle_mtime='' bundle_type='' bundle_owner='' bundle_mode='' local pre_identity='' pre_nlink='' pre_size='' pre_mtime='' pre_type='' pre_owner='' pre_mode='' local manifest_identity_before='' manifest_nlink_before='' manifest_size_before='' manifest_mtime_before='' local manifest_type_before='' manifest_owner_before='' manifest_mode_before='' manifest_record_before='' local manifest_identity_after='' manifest_nlink_after='' manifest_size_after='' manifest_mtime_after='' local manifest_type_after='' manifest_owner_after='' manifest_mode_after='' manifest_record_after='' local line='' hash='' relative='' target='' canonical_target='' target_record_before='' target_record_after='' local target_identity='' target_nlink='' target_size='' target_mtime='' target_type='' target_owner='' target_mode='' local inventory_path='' _snapshot_value='' _count_value=0 _bytes_value=0 local last_index=0 inventory_count=0 local -a inventory=() manifest_lines=() local -A seen_paths=() seen_inodes=() expected_inventory=() seen_inventory=() (( $# == 4 )) || return 1 _k3slra1_output_names_are_distinct "$out_count" "$out_bytes" "$out_snapshot" || return 1 _k3slra1_output_names_avoid 3 "$out_count" "$out_bytes" "$out_snapshot" bundle out_count out_bytes out_snapshot mount_root _selected_value pre_root manifest manifest_hex_before manifest_hex_after bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode manifest_identity_before manifest_nlink_before manifest_size_before manifest_mtime_before manifest_type_before manifest_owner_before manifest_mode_before manifest_record_before manifest_identity_after manifest_nlink_after manifest_size_after manifest_mtime_after manifest_type_after manifest_owner_after manifest_mode_after manifest_record_after line hash relative target canonical_target target_record_before target_record_after target_identity target_nlink target_size target_mtime target_type target_owner target_mode inventory_path _snapshot_value _count_value _bytes_value last_index inventory_count inventory manifest_lines seen_paths seen_inodes expected_inventory seen_inventory || return 1 mount_root="${bundle%/*}" [[ -n "$mount_root" ]] || return 1 _k3slra1_select_pre_bundle "$mount_root" _selected_value || return 1 [[ "$_selected_value" == "$bundle" ]] || return 1 pre_root="${bundle}/pre" manifest="${pre_root}/verification.manifest" _k3slra1_metadata_fields "$bundle" bundle_identity bundle_nlink bundle_size bundle_mtime bundle_type bundle_owner bundle_mode || return 1 _k3slra1_metadata_fields "$pre_root" pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode || return 1 _k3slra1_metadata_fields "$manifest" manifest_identity_before manifest_nlink_before manifest_size_before manifest_mtime_before manifest_type_before manifest_owner_before manifest_mode_before || return 1 _k3slra1_capture_manifest_hex "$manifest" manifest_hex_before || return 1 _k3slra1_sha256_record "$manifest" manifest_record_before || return 1 printf -v "expected_inventory[$manifest]" '%s' 1 mapfile -t manifest_lines <"$manifest" for line in "${manifest_lines[@]}"; do (( _count_value += 1 )) (( _count_value <= K3SLRA1_TARGET_COUNT )) || return 1 [[ "$line" =~ ^[0-9a-f]{64}\ \ \./[A-Za-z0-9._+/-]+$ ]] || return 1 hash="${line:0:64}" relative="${line:66}" (( ${#relative} <= K3SLRA1_PATH_MAX_BYTES )) || return 1 [[ "$relative" != './verification.manifest' ]] || return 1 [[ "$relative" != *//* ]] || return 1 [[ "$relative" != *'/./'* ]] || return 1 [[ "$relative" != *'/../'* ]] || return 1 [[ "$relative" != */. ]] || return 1 [[ "$relative" != */.. ]] || return 1 [[ "$relative" != */ ]] || return 1 [[ "${seen_paths[$relative]+set}" != set ]] || return 1 printf -v "seen_paths[$relative]" '%s' 1 target="${pre_root}/${relative#./}" _k3slra1_canonical_path "$target" canonical_target || return 1 [[ "$canonical_target" == "$target" ]] || return 1 _k3slra1_metadata_fields "$target" target_identity target_nlink target_size target_mtime target_type target_owner target_mode || return 1 [[ "$target_type" == 'regular file' ]] || return 1 [[ "$target_nlink" == 1 ]] || return 1 [[ "${target_identity%%:*}" == "${pre_identity%%:*}" ]] || return 1 [[ "${seen_inodes[$target_identity]+set}" != set ]] || return 1 printf -v "seen_inodes[$target_identity]" '%s' 1 target_record_before="${target_identity}|${target_nlink}|${target_size}|${target_mtime}|${target_type}|${target_owner}|${target_mode}" _k3slra1_sha256_record "$target" target_record_after || return 1 [[ "$target_record_after" == "${hash} ${target}" ]] || return 1 _k3slra1_metadata_fields "$target" target_identity target_nlink target_size target_mtime target_type target_owner target_mode || return 1 [[ "${target_identity}|${target_nlink}|${target_size}|${target_mtime}|${target_type}|${target_owner}|${target_mode}" == "$target_record_before" ]] || return 1 (( _bytes_value += 10#$target_size )) printf -v _snapshot_value '%s%s|%s|%s\n' "$_snapshot_value" "$relative" "$target_record_before" "$hash" printf -v "expected_inventory[$target]" '%s' 1 done (( _count_value == K3SLRA1_TARGET_COUNT )) || return 1 (( _bytes_value == K3SLRA1_TARGET_BYTES )) || return 1 mapfile -d '' -t inventory < <(_k3slra1_find_regular_packet "$pre_root") (( ${#inventory[@]} >= 1 )) || return 1 (( last_index = ${#inventory[@]} - 1 )) [[ "${inventory[$last_index]}" == RC=0 ]] || return 1 unset 'inventory[last_index]' for inventory_path in "${inventory[@]}"; do [[ -n "$inventory_path" ]] || return 1 [[ "$inventory_path" != STDERR ]] || return 1 [[ "${expected_inventory[$inventory_path]+set}" == set ]] || return 1 [[ "${seen_inventory[$inventory_path]+set}" != set ]] || return 1 printf -v "seen_inventory[$inventory_path]" '%s' 1 (( inventory_count += 1 )) done (( inventory_count == K3SLRA1_TARGET_COUNT + 1 )) || return 1 _k3slra1_metadata_fields "$manifest" manifest_identity_after manifest_nlink_after manifest_size_after manifest_mtime_after manifest_type_after manifest_owner_after manifest_mode_after || return 1 _k3slra1_capture_manifest_hex "$manifest" manifest_hex_after || return 1 _k3slra1_sha256_record "$manifest" manifest_record_after || return 1 [[ "$manifest_identity_after" == "$manifest_identity_before" ]] || return 1 [[ "$manifest_nlink_after" == "$manifest_nlink_before" ]] || return 1 [[ "$manifest_size_after" == "$manifest_size_before" ]] || return 1 [[ "$manifest_mtime_after" == "$manifest_mtime_before" ]] || return 1 [[ "$manifest_type_after" == "$manifest_type_before" ]] || return 1 [[ "$manifest_owner_after" == "$manifest_owner_before" ]] || return 1 [[ "$manifest_mode_after" == "$manifest_mode_before" ]] || return 1 [[ "$manifest_hex_after" == "$manifest_hex_before" ]] || return 1 [[ "$manifest_record_after" == "$manifest_record_before" ]] || return 1 printf -v _snapshot_value '%s%s\n%s\n%s\n' "$_snapshot_value" "$bundle_identity|$bundle_nlink|$bundle_size|$bundle_mtime|$bundle_type|$bundle_owner|$bundle_mode" "$pre_identity|$pre_nlink|$pre_size|$pre_mtime|$pre_type|$pre_owner|$pre_mode" "$manifest_identity_before|$manifest_nlink_before|$manifest_size_before|$manifest_mtime_before|$manifest_type_before|$manifest_owner_before|$manifest_mode_before|$manifest_record_before" printf -v "$out_count" '%s' "$_count_value" printf -v "$out_bytes" '%s' "$_bytes_value" printf -v "$out_snapshot" '%s' "$_snapshot_value" } _k3slra1_verify_manifest() { local bundle="${1-}" out_count="${2-}" out_bytes="${3-}" local _count_result='' _bytes_result='' _snapshot_result='' (( $# == 3 )) || return 1 _k3slra1_output_names_are_distinct "$out_count" "$out_bytes" || return 1 _k3slra1_output_names_avoid 2 "$out_count" "$out_bytes" bundle out_count out_bytes _count_result _bytes_result _snapshot_result || return 1 _k3slra1_analyze_manifest "$bundle" _count_result _bytes_result _snapshot_result || return 1 printf -v "$out_count" '%s' "$_count_result" printf -v "$out_bytes" '%s' "$_bytes_result" } _k3slra1_snapshot_metadata_for_relative() { local snapshot="${1-}" relative="${2-}" output_name="${3-}" local line='' value='' match_count=0 local -a snapshot_lines=() (( $# == 3 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 _k3slra1_output_names_avoid 1 "$output_name" snapshot relative output_name line value match_count snapshot_lines || return 1 [[ "$relative" == ./* ]] || return 1 mapfile -t snapshot_lines <<<"$snapshot" for line in "${snapshot_lines[@]}"; do if [[ "$line" == "${relative}|"* ]]; then (( match_count += 1 )) value="${line#"${relative}|"}" [[ "$value" =~ \|([0-9a-f]{64})$ ]] || return 1 value="${value%|${BASH_REMATCH[1]}}" fi done (( match_count == 1 )) || return 1 [[ "$value" =~ ^[0-9]+:[0-9]+\|1\|[0-9]+\|.+\|regular[[:space:]]file\|[0-9]+:[0-9]+\|[0-9]+$ ]] || return 1 printf -v "$output_name" '%s' "$value" } _k3slra1_sqlite_selected_path_matches() { local path="${1-}" expected_device="${2-}" expected_record="${3-}" canonical='' local identity='' nlink='' size='' mtime='' type='' owner='' mode='' current_record='' (( $# == 3 )) || return 1 _k3slra1_canonical_path "$path" canonical || return 1 [[ "$canonical" == "$path" ]] || return 1 _k3slra1_metadata_fields "$path" identity nlink size mtime type owner mode || return 1 [[ "${identity%%:*}" == "$expected_device" ]] || return 1 [[ "$nlink" == 1 ]] || return 1 [[ "$type" == 'regular file' ]] || return 1 current_record="${identity}|${nlink}|${size}|${mtime}|${type}|${owner}|${mode}" [[ "$current_record" == "$expected_record" ]] } _k3slra1_select_sqlite_layout_from_snapshot() { local bundle="${1-}" snapshot="${2-}" output_name="${3-}" path relative='' local expected_record='' canonical_count=0 legacy_count=0 _k3slra1_layout_value='' local pre_identity='' pre_nlink='' pre_size='' pre_mtime='' pre_type='' pre_owner='' pre_mode='' pre_device='' local -a selected_paths=() canonical_paths=("${bundle}/pre/${K3SLRA1_CANONICAL_DATABASE#./}" "${bundle}/pre/${K3SLRA1_CANONICAL_DATABASE#./}-wal" "${bundle}/pre/${K3SLRA1_CANONICAL_DATABASE#./}-shm") legacy_paths=("${bundle}/pre/${K3SLRA1_LEGACY_DATABASE#./}" "${bundle}/pre/${K3SLRA1_LEGACY_DATABASE#./}-wal" "${bundle}/pre/${K3SLRA1_LEGACY_DATABASE#./}-shm") (( $# == 3 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 _k3slra1_output_names_avoid 1 "$output_name" bundle snapshot output_name path relative expected_record canonical_count legacy_count pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode pre_device selected_paths canonical_paths legacy_paths || return 1 _k3slra1_metadata_fields "${bundle}/pre" pre_identity pre_nlink pre_size pre_mtime pre_type pre_owner pre_mode || return 1 pre_device="${pre_identity%%:*}" for path in "${canonical_paths[@]}"; do if [[ -e "$path" ]]; then (( canonical_count += 1 )) else if [[ -L "$path" ]]; then (( canonical_count += 1 )) fi fi done for path in "${legacy_paths[@]}"; do if [[ -e "$path" ]]; then (( legacy_count += 1 )) else if [[ -L "$path" ]]; then (( legacy_count += 1 )) fi fi done if (( canonical_count == 3 )); then (( legacy_count == 0 )) || return 1 _k3slra1_layout_value=canonical selected_paths=("${canonical_paths[@]}") else if (( legacy_count == 3 )); then (( canonical_count == 0 )) || return 1 _k3slra1_layout_value=legacy selected_paths=("${legacy_paths[@]}") else return 1 fi fi for path in "${selected_paths[@]}"; do relative="./${path#"${bundle}/pre/"}" _k3slra1_snapshot_metadata_for_relative "$snapshot" "$relative" expected_record || return 1 _k3slra1_sqlite_selected_path_matches "$path" "$pre_device" "$expected_record" || return 1 done printf -v "$output_name" '%s' "$_k3slra1_layout_value" } _k3slra1_select_sqlite_layout() { local bundle="${1-}" output_name="${2-}" count='' bytes='' snapshot='' (( $# == 2 )) || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 _k3slra1_output_names_avoid 1 "$output_name" bundle output_name count bytes snapshot path || return 1 _k3slra1_analyze_manifest "$bundle" count bytes snapshot || return 1 _k3slra1_select_sqlite_layout_from_snapshot "$bundle" "$snapshot" "$output_name" } _k3slra1_capture_file_hex() { local file="${1-}" maximum="${2-}" output_name="${3-}" size='' count='' od_output='' hex='' (( $# == 3 )) || return 1 [[ "$maximum" =~ ^[1-9][0-9]*$ ]] || return 1 _k3slra1_output_name_is_safe "$output_name" || return 1 [[ "$output_name" != file ]] || return 1 [[ "$output_name" != maximum ]] || return 1 [[ "$output_name" != output_name ]] || return 1 [[ "$output_name" != size ]] || return 1 [[ "$output_name" != count ]] || return 1 [[ "$output_name" != od_output ]] || return 1 [[ "$output_name" != hex ]] || return 1 _k3slra1_packet_line size-stat "$file" size || return 1 [[ "$size" =~ ^[0-9]+$ ]] || return 1 (( 10#$size <= 10#$maximum )) || return 1 _k3slra1_packet_line wc "$file" count || return 1 [[ "$count" == *"$file" ]] || return 1 count="${count%"$file"}" [[ "$count" == *[[:space:]] ]] || return 1 count="${count//[[:space:]]/}" [[ "$count" == "$size" ]] || return 1 _k3slra1_packet_value od "$file" od_output || return 1 [[ "$od_output" != *$'\r'* ]] || return 1 if [[ -n "$od_output" ]]; then [[ "$od_output" == *$'\n' ]] || return 1 od_output="${od_output%$'\n'}" [[ -n "$od_output" ]] || return 1 [[ "$od_output" != *$'\n' ]] || return 1 [[ "$od_output" != *$'\n\n'* ]] || return 1 fi hex="${od_output//[[:space:]]/}" if (( 10#$size == 0 )); then [[ -z "$hex" ]] || return 1 else [[ "$hex" =~ ^[0-9a-f]+$ ]] || return 1 (( ${#hex} == 10#$size * 2 )) || return 1 fi printf -v "$output_name" '%s' "$hex" } _k3slra1_sqlite_capture_transaction() { local database="${1-}" capture_root="${2-}" stdout_path="${3-}" stderr_path="${4-}" local parent_identity_before='' parent_nlink='' parent_size='' parent_mtime='' parent_type='' parent_owner='' parent_mode='' local parent_fd_identity_after='' parent_fd_nlink_after='' parent_fd_size_after='' local parent_fd_mtime_after='' parent_fd_type_after='' parent_fd_owner_after='' parent_fd_mode_after='' local stdout_identity_before='' stdout_nlink='' stdout_size='' stdout_mtime='' stdout_type='' stdout_owner='' stdout_mode='' local stdout_fd_identity_after='' stdout_fd_nlink_after='' stdout_fd_size_after='' local stdout_fd_mtime_after='' stdout_fd_type_after='' stdout_fd_owner_after='' stdout_fd_mode_after='' local stderr_identity_before='' stderr_nlink='' stderr_size='' stderr_mtime='' stderr_type='' stderr_owner='' stderr_mode='' local stderr_fd_identity='' stderr_fd_nlink='' stderr_fd_size='' stderr_fd_mtime='' stderr_fd_type='' stderr_fd_owner='' stderr_fd_mode='' local stderr_fd_identity_after='' stderr_fd_nlink_after='' stderr_fd_size_after='' local stderr_fd_mtime_after='' stderr_fd_type_after='' stderr_fd_owner_after='' stderr_fd_mode_after='' local parent_identity_after='' parent_nlink_after='' parent_size_after='' parent_mtime_after='' parent_type_after='' parent_owner_after='' parent_mode_after='' local stdout_identity_after='' stdout_nlink_after='' stdout_size_after='' stdout_mtime_after='' stdout_type_after='' stdout_owner_after='' stdout_mode_after='' local stderr_identity_after='' stderr_nlink_after='' stderr_size_after='' stderr_mtime_after='' stderr_type_after='' stderr_owner_after='' stderr_mode_after='' local stdout_hex='' stderr_hex='' validation_rc=0 child_rc=1 cleanup_rc=0 (( $# == 4 )) || return 1 _capture_entered=1 if _k3slra1_metadata_fields "$capture_root" parent_identity_before parent_nlink parent_size parent_mtime parent_type parent_owner parent_mode; then : else validation_rc=1 fi if _k3slra1_metadata_fields "$stdout_path" stdout_identity_before stdout_nlink stdout_size stdout_mtime stdout_type stdout_owner stdout_mode; then : else validation_rc=1 fi if _k3slra1_metadata_fields "$stderr_path" stderr_identity_before stderr_nlink stderr_size stderr_mtime stderr_type stderr_owner stderr_mode; then : else validation_rc=1 fi if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/8" stderr_fd_identity stderr_fd_nlink stderr_fd_size stderr_fd_mtime stderr_fd_type stderr_fd_owner stderr_fd_mode; then : else validation_rc=1 fi [[ "$parent_type" == directory ]] || validation_rc=1 [[ "$parent_owner" == 0:0 ]] || validation_rc=1 [[ "$parent_mode" == 700 ]] || validation_rc=1 [[ "$_stage_parent_fd_type" == directory ]] || validation_rc=1 [[ "$_stage_parent_fd_owner" == 0:0 ]] || validation_rc=1 [[ "$_stage_parent_fd_mode" == 700 ]] || validation_rc=1 [[ "$_stage_parent_identity" == "$parent_identity_before" ]] || validation_rc=1 [[ "$_stage_parent_fd_identity" == "$parent_identity_before" ]] || validation_rc=1 [[ "$stdout_type" == 'regular file' ]] || validation_rc=1 [[ "$stderr_type" == 'regular file' ]] || validation_rc=1 [[ "$stdout_owner" == 0:0 ]] || validation_rc=1 [[ "$stderr_owner" == 0:0 ]] || validation_rc=1 [[ "$stdout_mode" == 600 ]] || validation_rc=1 [[ "$stderr_mode" == 600 ]] || validation_rc=1 [[ "$stdout_nlink" == 1 ]] || validation_rc=1 [[ "$stderr_nlink" == 1 ]] || validation_rc=1 [[ "$_stage_stdout_fd_type" == 'regular file' ]] || validation_rc=1 [[ "$stderr_fd_type" == 'regular file' ]] || validation_rc=1 [[ "$_stage_stdout_fd_owner" == 0:0 ]] || validation_rc=1 [[ "$stderr_fd_owner" == 0:0 ]] || validation_rc=1 [[ "$_stage_stdout_fd_mode" == 600 ]] || validation_rc=1 [[ "$stderr_fd_mode" == 600 ]] || validation_rc=1 [[ "$_stage_stdout_fd_nlink" == 1 ]] || validation_rc=1 [[ "$stderr_fd_nlink" == 1 ]] || validation_rc=1 [[ "$stdout_identity_before" == "$_stage_stdout_identity" ]] || validation_rc=1 [[ "$stdout_identity_before" == "$_stage_stdout_fd_identity" ]] || validation_rc=1 [[ "$stderr_identity_before" == "$stderr_fd_identity" ]] || validation_rc=1 [[ "$stdout_size" == "$_stage_stdout_fd_size" ]] || validation_rc=1 [[ "$stderr_size" == "$stderr_fd_size" ]] || validation_rc=1 [[ "$stdout_mtime" == "$_stage_stdout_fd_mtime" ]] || validation_rc=1 [[ "$stderr_mtime" == "$stderr_fd_mtime" ]] || validation_rc=1 [[ "$stdout_type" == "$_stage_stdout_fd_type" ]] || validation_rc=1 [[ "$stderr_type" == "$stderr_fd_type" ]] || validation_rc=1 [[ "$stdout_owner" == "$_stage_stdout_fd_owner" ]] || validation_rc=1 [[ "$stderr_owner" == "$stderr_fd_owner" ]] || validation_rc=1 [[ "$stdout_mode" == "$_stage_stdout_fd_mode" ]] || validation_rc=1 [[ "$stderr_mode" == "$stderr_fd_mode" ]] || validation_rc=1 [[ "$stderr_size" == 0 ]] || validation_rc=1 [[ "$stdout_identity_before" != "$stderr_identity_before" ]] || validation_rc=1 if (( validation_rc == 0 )); then if _k3slra1_command /usr/bin/env -i PATH=/usr/sbin:/usr/bin:/sbin:/bin LC_ALL=C "HOME=${capture_root}/home" /usr/bin/sqlite3 -safe -nofollow -readonly -batch -bail -noheader -init /dev/null "$database" "$K3SLRA1_SQLITE_QUERY" >&7 2>&8; then child_rc=0 else child_rc=$? fi fi if _k3slra1_metadata_fields "$stdout_path" stdout_identity_after stdout_nlink_after stdout_size_after stdout_mtime_after stdout_type_after stdout_owner_after stdout_mode_after; then : else validation_rc=1 fi if _k3slra1_metadata_fields "$stderr_path" stderr_identity_after stderr_nlink_after stderr_size_after stderr_mtime_after stderr_type_after stderr_owner_after stderr_mode_after; then : else validation_rc=1 fi if _k3slra1_metadata_fields "$capture_root" parent_identity_after parent_nlink_after parent_size_after parent_mtime_after parent_type_after parent_owner_after parent_mode_after; then : else validation_rc=1 fi if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/6" parent_fd_identity_after parent_fd_nlink_after parent_fd_size_after parent_fd_mtime_after parent_fd_type_after parent_fd_owner_after parent_fd_mode_after; then : else validation_rc=1 fi if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/7" stdout_fd_identity_after stdout_fd_nlink_after stdout_fd_size_after stdout_fd_mtime_after stdout_fd_type_after stdout_fd_owner_after stdout_fd_mode_after; then : else validation_rc=1 fi if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/8" stderr_fd_identity_after stderr_fd_nlink_after stderr_fd_size_after stderr_fd_mtime_after stderr_fd_type_after stderr_fd_owner_after stderr_fd_mode_after; then : else validation_rc=1 fi [[ "$parent_identity_after" == "$parent_identity_before" ]] || validation_rc=1 [[ "$parent_identity_after" == "$parent_fd_identity_after" ]] || validation_rc=1 [[ "$parent_fd_identity_after" == "$_stage_parent_fd_identity" ]] || validation_rc=1 [[ "$parent_type_after" == directory ]] || validation_rc=1 [[ "$parent_fd_type_after" == directory ]] || validation_rc=1 [[ "$parent_owner_after" == 0:0 ]] || validation_rc=1 [[ "$parent_fd_owner_after" == 0:0 ]] || validation_rc=1 [[ "$parent_mode_after" == 700 ]] || validation_rc=1 [[ "$parent_fd_mode_after" == 700 ]] || validation_rc=1 [[ "$stdout_identity_after" == "$stdout_identity_before" ]] || validation_rc=1 [[ "$stdout_identity_after" == "$stdout_fd_identity_after" ]] || validation_rc=1 [[ "$stdout_nlink_after" == 1 ]] || validation_rc=1 [[ "$stdout_fd_nlink_after" == 1 ]] || validation_rc=1 [[ "$stdout_type_after" == 'regular file' ]] || validation_rc=1 [[ "$stdout_fd_type_after" == 'regular file' ]] || validation_rc=1 [[ "$stdout_owner_after" == 0:0 ]] || validation_rc=1 [[ "$stdout_fd_owner_after" == 0:0 ]] || validation_rc=1 [[ "$stdout_mode_after" == 600 ]] || validation_rc=1 [[ "$stdout_fd_mode_after" == 600 ]] || validation_rc=1 [[ "$stdout_size_after" == "$stdout_fd_size_after" ]] || validation_rc=1 [[ "$stdout_mtime_after" == "$stdout_fd_mtime_after" ]] || validation_rc=1 [[ "$stderr_identity_after" == "$stderr_identity_before" ]] || validation_rc=1 [[ "$stderr_identity_after" == "$stderr_fd_identity_after" ]] || validation_rc=1 [[ "$stderr_nlink_after" == 1 ]] || validation_rc=1 [[ "$stderr_fd_nlink_after" == 1 ]] || validation_rc=1 [[ "$stderr_type_after" == 'regular file' ]] || validation_rc=1 [[ "$stderr_fd_type_after" == 'regular file' ]] || validation_rc=1 [[ "$stderr_owner_after" == 0:0 ]] || validation_rc=1 [[ "$stderr_fd_owner_after" == 0:0 ]] || validation_rc=1 [[ "$stderr_mode_after" == 600 ]] || validation_rc=1 [[ "$stderr_fd_mode_after" == 600 ]] || validation_rc=1 [[ "$stderr_size_after" == "$stderr_fd_size_after" ]] || validation_rc=1 [[ "$stderr_mtime_after" == "$stderr_fd_mtime_after" ]] || validation_rc=1 if (( validation_rc == 0 )); then _k3slra1_capture_file_hex "$stdout_path" 16 stdout_hex || validation_rc=1 _k3slra1_capture_file_hex "$stderr_path" 16 stderr_hex || validation_rc=1 [[ "$stdout_hex" == 6f6b0a ]] || validation_rc=1 [[ -z "$stderr_hex" ]] || validation_rc=1 (( child_rc == 0 )) || validation_rc=1 fi _k3slra1_remove_owned_capture "$stdout_path" "$stdout_identity_before" || cleanup_rc=1 _k3slra1_remove_owned_capture "$stderr_path" "$stderr_identity_before" || cleanup_rc=1 if _k3slra1_metadata_fields "$capture_root" parent_identity_after parent_nlink_after parent_size_after parent_mtime_after parent_type_after parent_owner_after parent_mode_after; then : else cleanup_rc=1 fi [[ "$parent_identity_after" == "$parent_identity_before" ]] || cleanup_rc=1 (( cleanup_rc == 0 )) || return 1 case "${_capture_signal-0}" in 130|143) return "$_capture_signal" ;; esac (( validation_rc == 0 )) || return 1 } _k3slra1_remove_owned_capture() { local path="${1-}" expected_identity="${2-}" canonical='' local identity='' nlink='' size='' mtime='' type='' owner='' mode='' (( $# == 2 )) || return 1 [[ -n "$expected_identity" ]] || return 1 _k3slra1_canonical_path "$path" canonical || return 1 [[ "$canonical" == "$path" ]] || return 1 _k3slra1_metadata_fields "$path" identity nlink size mtime type owner mode || return 1 [[ "$identity" == "$expected_identity" ]] || return 1 [[ "$nlink" =~ ^[1-9][0-9]*$ ]] || return 1 [[ "$type" == 'regular file' ]] || return 1 _k3slra1_command /usr/bin/unlink "$path" >/dev/null 2>&1 || return 1 [[ ! -e "$path" ]] || return 1 [[ ! -L "$path" ]] } _k3slra1_remove_partial_capture() { local path="${1-}" expected_device="${2-}" expected_identity="${3-}" canonical='' local identity='' nlink='' size='' mtime='' type='' owner='' mode='' (( $# == 3 )) || return 1 _k3slra1_canonical_path "$path" canonical || return 1 [[ "$canonical" == "$path" ]] || return 1 _k3slra1_metadata_fields "$path" identity nlink size mtime type owner mode || return 1 [[ "$identity" == "$expected_identity" ]] || return 1 [[ "$type" == 'regular file' ]] || return 1 [[ "$nlink" == 1 ]] || return 1 [[ "$owner" == 0:0 ]] || return 1 [[ "$mode" == 600 ]] || return 1 [[ "${identity%%:*}" == "$expected_device" ]] || return 1 _k3slra1_command /usr/bin/unlink "$path" >/dev/null 2>&1 || return 1 [[ ! -e "$path" ]] || return 1 [[ ! -L "$path" ]] } _k3slra1_stderr_open_boundary() { : } _k3slra1_sqlite_stdout_stage() { local database="${1-}" capture_root="${2-}" stdout_path="${3-}" stderr_path="${4-}" local _stage_parent_identity='' _stage_parent_nlink='' _stage_parent_size='' local _stage_parent_mtime='' _stage_parent_type='' _stage_parent_owner='' _stage_parent_mode='' local _stage_parent_fd_identity='' _stage_parent_fd_nlink='' _stage_parent_fd_size='' local _stage_parent_fd_mtime='' _stage_parent_fd_type='' _stage_parent_fd_owner='' _stage_parent_fd_mode='' local _stage_stdout_identity='' _stage_stdout_nlink='' _stage_stdout_size='' local _stage_stdout_mtime='' _stage_stdout_type='' _stage_stdout_owner='' _stage_stdout_mode='' local _stage_stdout_fd_identity='' _stage_stdout_fd_nlink='' _stage_stdout_fd_size='' local _stage_stdout_fd_mtime='' _stage_stdout_fd_type='' _stage_stdout_fd_owner='' _stage_stdout_fd_mode='' local stage_rc=1 cleanup_rc=0 validation_rc=0 (( $# == 4 )) || return 1 if _k3slra1_metadata_fields "$capture_root" _stage_parent_identity _stage_parent_nlink _stage_parent_size _stage_parent_mtime _stage_parent_type _stage_parent_owner _stage_parent_mode; then : else validation_rc=1 fi if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/6" _stage_parent_fd_identity _stage_parent_fd_nlink _stage_parent_fd_size _stage_parent_fd_mtime _stage_parent_fd_type _stage_parent_fd_owner _stage_parent_fd_mode; then : else validation_rc=1 fi if _k3slra1_metadata_fields "$stdout_path" _stage_stdout_identity _stage_stdout_nlink _stage_stdout_size _stage_stdout_mtime _stage_stdout_type _stage_stdout_owner _stage_stdout_mode; then : else validation_rc=1 fi if _k3slra1_fd_metadata_fields "/proc/${BASHPID}/fd/7" _stage_stdout_fd_identity _stage_stdout_fd_nlink _stage_stdout_fd_size _stage_stdout_fd_mtime _stage_stdout_fd_type _stage_stdout_fd_owner _stage_stdout_fd_mode; then : else validation_rc=1 fi [[ "$_stage_parent_identity" == "$_stage_parent_fd_identity" ]] || validation_rc=1 [[ "$_stage_parent_type" == directory ]] || validation_rc=1 [[ "$_stage_parent_fd_type" == directory ]] || validation_rc=1 [[ "$_stage_parent_owner" == 0:0 ]] || validation_rc=1 [[ "$_stage_parent_fd_owner" == 0:0 ]] || validation_rc=1 [[ "$_stage_parent_mode" == 700 ]] || validation_rc=1 [[ "$_stage_parent_fd_mode" == 700 ]] || validation_rc=1 [[ "$_stage_stdout_identity" == "$_stage_stdout_fd_identity" ]] || validation_rc=1 [[ "$_stage_stdout_type" == 'regular file' ]] || validation_rc=1 [[ "$_stage_stdout_fd_type" == 'regular file' ]] || validation_rc=1 [[ "$_stage_stdout_nlink" == 1 ]] || validation_rc=1 [[ "$_stage_stdout_fd_nlink" == 1 ]] || validation_rc=1 [[ "$_stage_stdout_size" == 0 ]] || validation_rc=1 [[ "$_stage_stdout_fd_size" == 0 ]] || validation_rc=1 [[ "$_stage_stdout_identity" != "$_stage_parent_identity" ]] || validation_rc=1 if (( validation_rc == 0 )); then if _k3slra1_stderr_open_boundary; then if _k3slra1_sqlite_capture_transaction "$database" "$capture_root" "$stdout_path" "$stderr_path" 8>"$stderr_path"; then stage_rc=0 else stage_rc=$? fi fi fi if (( _capture_entered == 0 )); then _k3slra1_remove_partial_capture "$stdout_path" "${_stage_parent_identity%%:*}" "$_stage_stdout_identity" || cleanup_rc=1 fi (( cleanup_rc == 0 )) || return 1 case "$stage_rc" in 0) case "${_capture_signal-0}" in 130|143) return "$_capture_signal" ;; esac (( validation_rc == 0 )) || return 1 return 0 ;; 130|143) return "$stage_rc" ;; *) if (( _capture_entered == 0 )); then case "${_capture_signal-0}" in 130|143) return "$_capture_signal" ;; esac fi return 1 ;; esac } _k3slra1_sqlite_quick_check() ( local bundle="${1-}" layout="${2-}" capture_root="${3-}" database_relative='' local stdout_path='' stderr_path='' transaction_rc=1 local capture_canonical='' capture_identity='' capture_nlink='' capture_size='' capture_mtime='' local capture_type='' capture_owner='' capture_mode='' local _capture_entered=0 _capture_signal=0 (( $# == 3 )) || return 1 case "$layout" in canonical) database_relative="$K3SLRA1_CANONICAL_DATABASE" ;; legacy) database_relative="$K3SLRA1_LEGACY_DATABASE" ;; *) return 1 ;; esac stdout_path="${capture_root}/sqlite.stdout" stderr_path="${capture_root}/sqlite.stderr" _k3slra1_canonical_path "$capture_root" capture_canonical || return 1 [[ "$capture_canonical" == "$capture_root" ]] || return 1 _k3slra1_metadata_fields "$capture_root" capture_identity capture_nlink capture_size capture_mtime capture_type capture_owner capture_mode || return 1 [[ "$capture_type" == directory ]] || return 1 [[ "$capture_owner" == 0:0 ]] || return 1 [[ "$capture_mode" == 700 ]] || return 1 [[ ! -e "$stdout_path" ]] || return 1 [[ ! -L "$stdout_path" ]] || return 1 [[ ! -e "$stderr_path" ]] || return 1 [[ ! -L "$stderr_path" ]] || return 1 umask 077 set -o noclobber trap '_capture_signal=130; if (( transaction_rc == 0 )); then transaction_rc=130; fi' INT trap '_capture_signal=143; if (( transaction_rc == 0 )); then transaction_rc=143; fi' TERM if _k3slra1_sqlite_stdout_stage "${bundle}/pre/${database_relative#./}" "$capture_root" "$stdout_path" "$stderr_path" 2>/dev/null 6<"$capture_root" 7>"$stdout_path"; then transaction_rc=0 else transaction_rc=$? fi if (( _capture_signal != 0 && transaction_rc == 0 )); then transaction_rc=$_capture_signal fi case "$transaction_rc" in 0) return 0 ;; 130|143) return "$transaction_rc" ;; *) return 1 ;; esac )