Qualify guest version through one-way raw evidence before permit

This commit is contained in:
dh
2026-10-04 16:08:41 +02:00
parent 6122be2cef
commit 9164fe451f
3 changed files with 98 additions and 78 deletions
+17 -25
View File
@@ -101,21 +101,19 @@ read_scalar() {
# BEGIN native SystemVersion plist request helpers
read_native_system_version() {
# Recovery has Bash 3.2 before .NET. Read bytes here; XML is parsed by the
# existing owned host controller, never by shell or VERSION metadata.
# Recovery has Bash 3.2 before .NET. The numerical candidate is provisional;
# only the owned host's complete XML/evidence binding can qualify readiness.
local LC_ALL=C source="/System/Library/CoreServices/SystemVersion.plist"
local value status owner reply started=$SECONDS invalid_bytes
local value status owner candidate remainder started=$SECONDS invalid_bytes
local raw="$STATE_DIR/native-system-version.plist"
local ready="$STATE_DIR/native-system-version.request"
local response="$STATE_DIR/native-system-version.reply"
NATIVE_VERSION_ERROR=native_system_version_read_failed
printf '[native-version-start] method=guest-file/host-xml source=%s seconds=%s\n' "$source" "$started" >&3
IFS= read -r -n 81 -d '' owner < "$STATE_DIR/run.owner"; status=$?
(( status == 1 && ${#owner} <= 80 )) &&
[ "$owner" = "$PROOF_TOKEN"$'\n' ] || { NATIVE_VERSION_ERROR=native_system_version_foreign_owner; return 1; }
[ ! -e "$ready" ] && [ ! -L "$ready" ] &&
[ ! -e "$raw" ] && [ ! -L "$raw" ] &&
[ ! -e "$response" ] && [ ! -L "$response" ] || { NATIVE_VERSION_ERROR=native_system_version_stale_exchange; return 1; }
[ ! -e "$raw" ] && [ ! -L "$raw" ] || { NATIVE_VERSION_ERROR=native_system_version_stale_exchange; return 1; }
[ -f "$source" ] || return 1
IFS= read -r -n 4097 -d '' value < "$source"; status=$?
# EOF is mandatory. NUL stops read with status 0; 4097 is the overbound sentinel.
@@ -128,25 +126,19 @@ read_native_system_version() {
# Publish this final marker only after the complete raw write has closed.
printf '%s\n%s\n%s\nready:%s\n' "$PROOF_TOKEN" "$source" "${#value}" "$PROOF_TOKEN" > "$ready" || return 1
printf '[native-version-request] method=guest-file/host-xml source=%s bytes=%s seconds=%s\n' "$source" "${#value}" "$SECONDS" >&3
while (( SECONDS - started < 180 )); do
if [ -e "$response" ] || [ -L "$response" ]; then
[ -f "$response" ] && [ ! -L "$response" ] || { NATIVE_VERSION_ERROR=native_system_version_invalid_reply; return 1; }
IFS= read -r -n 81 -d '' reply < "$response"; status=$?
(( status == 1 && ${#reply} <= 80 )) && [[ "$reply" = *$'\n' ]] || { NATIVE_VERSION_ERROR=native_system_version_invalid_reply; return 1; }
reply=${reply%$'\n'}
if [[ "$reply" =~ ^([0-9a-f]{32}):([0-9]+\.[0-9]+(\.[0-9]+)?)$ ]] && [ "${BASH_REMATCH[1]}" = "$PROOF_TOKEN" ]; then
SCALAR="${BASH_REMATCH[2]}"
NATIVE_VERSION_ERROR=""
printf '[native-version-result] method=guest-file/host-xml source=%s version=%s elapsed=%ss\n' "$source" "$SCALAR" "$((SECONDS - started))" >&3
return 0
fi
NATIVE_VERSION_ERROR=native_system_version_rejected_reply
return 1
fi
IFS= read -r -t 1 -u 9 unused || :
done
NATIVE_VERSION_ERROR=native_system_version_reply_timeout
return 1
# This is a candidate from exactly these bytes, not an XML validity check.
NATIVE_VERSION_ERROR=native_system_version_candidate_invalid
[[ "$value" == *'<key>ProductVersion</key>'* ]] || return 1
remainder=${value#*'<key>ProductVersion</key>'}
remainder=${remainder#"${remainder%%[![:space:]]*}"}
[[ "$remainder" == '<string>'* ]] || return 1
remainder=${remainder#'<string>'}
candidate=${remainder%%'</string>'*}
[ "$candidate" != "$remainder" ] && [[ "$candidate" =~ ^[0-9]+\.[0-9]+(\.[0-9]+)?$ ]] || return 1
SCALAR="$candidate"
NATIVE_VERSION_ERROR=""
printf '[native-version-candidate] method=guest-file/host-xml source=%s candidate=%s qualified=false elapsed=%ss\n' "$source" "$SCALAR" "$((SECONDS - started))" >&3
return 0
}
# END native SystemVersion plist request helpers
# BEGIN disk IPC diagnostic