This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python3
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
"""Validate the fail-closed Phase-0.5 machine-readable decision records."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
BLOCKED_SHA256 = "4be1c17b4964f2b68c39b5145bc4af4619c32512d60269ecf5c39728b390fa63"
|
||||
|
||||
|
||||
def load(path: Path) -> dict[str, object]:
|
||||
document = json.loads(path.read_text(encoding="utf-8"))
|
||||
if not isinstance(document, dict):
|
||||
raise RuntimeError(f"{path}: expected object")
|
||||
return document
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--root", type=Path, required=True)
|
||||
args = parser.parse_args()
|
||||
root = args.root.resolve()
|
||||
|
||||
audit = load(root / "manifests/runtime/phase-0.5-startup-audit.json")
|
||||
decision = load(root / "manifests/runtime/minimal-startup-artifact-decision.json")
|
||||
matrix = load(root / "manifests/runtime/kernelwrite-proof-matrix.json")
|
||||
denylist = load(root / "manifests/artifact-denylist.json")
|
||||
|
||||
if audit.get("decision") != "BLOCKED" or audit["artifact"]["built"] is not False:
|
||||
raise RuntimeError("startup audit no longer blocks artifact construction")
|
||||
if audit["artifact"]["execution_eligible"] is not False:
|
||||
raise RuntimeError("startup audit claims execution eligibility")
|
||||
if audit["loader_evidence"]["caller_source_present"] is not False:
|
||||
raise RuntimeError("audit claims an unreviewed loader caller")
|
||||
required_reachable = {
|
||||
"__patch_init",
|
||||
"kernel_copyin",
|
||||
"kernel_copyout",
|
||||
"kernel_set_ucred_attrs",
|
||||
"kernel_set_ucred_caps",
|
||||
}
|
||||
reachable = set(audit["crt1_static_evidence"]["reachable_prohibited_functions"])
|
||||
if reachable != required_reachable:
|
||||
raise RuntimeError(f"reachable kernel-write inventory changed: {reachable}")
|
||||
|
||||
if decision.get("decision") != "BLOCKED" or decision["artifact"]["built"] is not False:
|
||||
raise RuntimeError("non-build decision changed")
|
||||
if decision["execution"]["execution_eligible"] is not False:
|
||||
raise RuntimeError("non-build record claims execution eligibility")
|
||||
if any(value is not None for value in (
|
||||
decision["artifact"]["filename"],
|
||||
decision["artifact"]["sha256"],
|
||||
decision["artifact"]["size"],
|
||||
)):
|
||||
raise RuntimeError("non-build decision fabricates artifact bytes")
|
||||
|
||||
statuses = {entry["status"] for entry in matrix["entries"]}
|
||||
if statuses != {"SAFE", "UNSAFE", "UNPROVEN"}:
|
||||
raise RuntimeError(f"review matrix lacks a status class: {statuses}")
|
||||
if [entry["sha256"] for entry in denylist["entries"]] != [BLOCKED_SHA256]:
|
||||
raise RuntimeError("permanent blocked hash changed")
|
||||
print("Phase-0.5 machine-readable BLOCKED decision is consistent")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user