4"""Require download-to-file and SHA-256 verification for bootstrap installers."""
6from __future__
import annotations
13from pathlib
import Path
15from download_installers_macos
import check_macos_cleanup, macos_cleanup_mutations
19 [
"git",
"rev-parse",
"--show-toplevel"],
26DOCKERFILE =
".devcontainer/Dockerfile"
27PROVISION =
"scripts/dev/provision_dev_box_toolchain.sh"
28MAC_SETUP =
"scripts/emu/setup_macos.sh"
30 "SHELLCHECK_SHA256_X86_64",
31 "SHELLCHECK_SHA256_AARCH64",
34 "ACTIONLINT_SHA256_AMD64",
35 "ACTIONLINT_SHA256_ARM64",
37 "JUST_SHA256_AARCH64",
38 "HADOLINT_SHA256_X86_64",
39 "HADOLINT_SHA256_ARM64",
42 "ARM_GCC_SHA256_X86_64",
43 "ARM_GCC_SHA256_AARCH64",
44 "ARM_GCC_SHA256_DARWIN_X86_64",
45 "ARM_GCC_SHA256_DARWIN_ARM64",
47ARM_RELEASE_RE = re.compile(
r"^[0-9]+\.[0-9]+\.rel[1-9][0-9]*$")
48MAC_DOCKER_ARG_READER =
r"""{
50 if ! value="$(awk -v name="${name}" '
51 function inspect_instruction( body, line, lower, target) {
53 sub(/^[[:blank:]]*/, "", line)
55 if (substr(lower, 1, 3) != "arg" ||
56 substr(line, 4, 1) !~ /[[:blank:]]/) {
59 body = substr(line, 5)
60 sub(/^[[:blank:]]+/, "", body)
61 target = "(^|[[:blank:]])" name "([=[:blank:]]|$)"
66 if (continued || index(body, name "=") != 1) {
70 value = substr(body, length(name) + 2)
74 if (physical ~ /^[[:blank:]]*(#.*)?$/) {
77 has_continuation = physical ~ /\\[[:blank:]]*$/
78 if (has_continuation) {
79 sub(/\\[[:blank:]]*$/, "", physical)
80 logical = logical physical
84 logical = logical physical
94 if (count != 1 || invalid) exit 2
97 ' "${dockerfile}")"; then
98 echo "ERROR: expected one canonical ARG ${name}=... in ${dockerfile}." >&2
101 printf '%s' "${value}"
103TLS_FLAGS =
"--proto '=https' --proto-redir '=https' --tlsv1.2"
104DOCKER_DOWNLOAD_MARKER = {
105 "shellcheck": f
"curl {TLS_FLAGS} -fsSL -o /tmp/shellcheck.tar.xz",
106 "shfmt": f
"curl {TLS_FLAGS} -fsSL -o /tmp/shfmt",
107 "actionlint": f
"curl {TLS_FLAGS} -fsSL -o /tmp/actionlint.tar.gz",
108 "just": f
"curl {TLS_FLAGS} -fsSL -o /tmp/just.tar.gz",
109 "hadolint": f
"curl {TLS_FLAGS} -fsSL -o /tmp/hadolint",
111TOOLS = (
"shellcheck",
"shfmt",
"actionlint",
"just",
"hadolint")
112ARCHIVE_TOOLS = (
"shellcheck",
"actionlint",
"just")
113DOCKER_VERIFY_MARKER = {
114 "shellcheck":
'"${scsha}" /tmp/shellcheck.tar.xz | sha256sum -c -',
115 "shfmt":
'"${shsha}" /tmp/shfmt | sha256sum -c -',
116 "actionlint":
'"${alsha}" /tmp/actionlint.tar.gz | sha256sum -c -',
117 "just":
'"${justsha}" /tmp/just.tar.gz | sha256sum -c -',
118 "hadolint":
'"${hsha}" /tmp/hadolint | sha256sum -c -',
120DOCKER_ARCHIVE_MEMBER = {
121 "shellcheck":
'"shellcheck-v${SHELLCHECK_VERSION}/shellcheck"',
122 "actionlint":
"-C /tmp/actionlint actionlint",
123 "just":
"-C /tmp/just just",
125PROVISION_ARCHIVE_MEMBER = {
126 "shellcheck":
'"shellcheck-v${version}/shellcheck"',
127 "actionlint":
'-C "${tmp}/extract" actionlint',
128 "just":
'-C "${tmp}/extract" just',
131 "shellcheck":
"# cmake-format",
132 "shfmt":
"# cmake-format",
133 "actionlint":
"# just",
134 "just":
"# hadolint",
135 "hadolint":
"# Create a non-root user",
138 "shellcheck":
"install_shfmt()",
139 "shfmt":
"install_actionlint()",
140 "actionlint":
"install_hadolint()",
141 "hadolint":
"install_just()",
142 "just":
"install_doxygen()",
146def _active(text: str) -> str:
147 """Discard comment-only lines and join shell continuations."""
148 code =
"\n".join(line
for line
in text.splitlines()
if not line.lstrip().startswith(
"#"))
149 return re.sub(
r"\\\n\s*",
" ", code)
152def _normalise_shell(text: str) -> str:
153 """Collapse insignificant shell whitespace for exact statement checks."""
154 return " ".join(_active(text).split())
157def _exact_hex_assignment(text: str, name: str, length: int) -> str |
None:
158 """Return one indented literal hex assignment and reject every duplicate."""
159 pattern = rf
'(?m)^[ \t]*{re.escape(name)}="([0-9a-f]{{{length}}})"[ \t]*$'
160 matches = re.findall(pattern, text)
161 assignments = re.findall(rf
"(?m)^[ \t]*{re.escape(name)}[+?]?=", text)
162 return matches[0]
if len(matches) == 1
and len(assignments) == 1
else None
165def _unsafe_pipeline(text: str) -> bool:
166 """Return whether downloaded bytes flow directly to a parser or shell."""
167 active = _active(text)
169 re.search(
r"\bcurl\b[^\n;]*\|\s*(?:bash|sh|tar)\b", active)
170 or re.search(
r"\$\(\s*curl\b", active)
174def _section(text: str, start: str, end: str) -> str:
175 """Return a required text section, or an empty string when anchors drift."""
176 before, marker, rest = text.partition(start)
180 body, marker, _after = rest.partition(end)
181 return body
if marker
else ""
184def _docker_instructions(text: str) -> tuple[tuple[str, bool], ...]:
185 """Return Docker logical instructions and whether they used continuation."""
186 instructions: list[tuple[str, bool]] = []
189 for physical
in text.splitlines():
190 if not physical.strip()
or physical.lstrip().startswith(
"#"):
192 match = re.search(
r"\\[ \t]*$", physical)
193 if match
is not None:
194 logical += physical[: match.start()]
198 instructions.append((logical, continued))
202 instructions.append((logical,
True))
203 return tuple(instructions)
206def _docker_args(text: str, name: str) -> tuple[str |
None, ...]:
207 """Return every Docker ARG occurrence, marking non-canonical forms invalid."""
208 values: list[str |
None] = []
209 target = re.compile(rf
"(?:^|[ \t]){re.escape(name)}(?=$|[= \t])")
210 instruction = re.compile(
r"^[ \t]*(?i:ARG)[ \t]+(.*)$")
211 for logical, continued
in _docker_instructions(text):
212 match = instruction.fullmatch(logical)
215 body = match.group(1).lstrip()
216 if target.search(body)
is None:
219 if continued
or not body.startswith(prefix):
222 values.append(body[len(prefix) :])
226def _docker_arg(text: str, name: str) -> str |
None:
227 """Return a canonical Docker ARG only when it occurs exactly once."""
228 values = _docker_args(text, name)
229 return values[0]
if len(values) == 1
and values[0]
is not None else None
232def _check_arm_docker_pins(text: str) -> list[str]:
233 """Require exact-one, well-formed Arm release and digest ARGs."""
234 findings: list[str] = []
235 release_values = _docker_args(text,
"ARM_GCC_RELEASE")
236 if len(release_values) != 1
or release_values[0]
is None:
237 findings.append(f
"{DOCKERFILE}: expected one canonical ARG ARM_GCC_RELEASE")
238 elif ARM_RELEASE_RE.fullmatch(release_values[0])
is None:
239 findings.append(f
"{DOCKERFILE}: ARM_GCC_RELEASE must match N.N.relN")
240 for name
in ARM_SHA_ARGS:
241 values = _docker_args(text, name)
242 if len(values) != 1
or values[0]
is None:
243 findings.append(f
"{DOCKERFILE}: expected one canonical ARG {name}")
244 elif re.fullmatch(
r"[0-9a-f]{64}", values[0])
is None:
245 findings.append(f
"{DOCKERFILE}: ARG {name} is not a 64-hex sha256")
249def check_dockerfile(text: str) -> list[str]:
250 """Check the canonical release pins and Docker install blocks."""
251 findings: list[str] = []
253 f
"{DOCKERFILE}: missing 64-hex ARG {name}"
255 if not re.search(rf
"^ARG {name}=[0-9a-f]{{64}}$", text, re.MULTILINE)
257 findings.extend(_check_arm_docker_pins(text))
258 if _unsafe_pipeline(text):
259 findings.append(f
"{DOCKERFILE}: curl output is piped directly to a shell/archive parser")
260 if "just.systems/install.sh" in text:
261 findings.append(f
"{DOCKERFILE}: mutable Just installer script is forbidden")
263 start =
"ARG SHELLCHECK_VERSION=" if tool ==
"shfmt" else f
"ARG {tool.upper()}_VERSION="
264 block = _section(text, start, DOCKER_END[tool])
265 active = _active(block)
268 or DOCKER_VERIFY_MARKER[tool]
not in active
269 or DOCKER_DOWNLOAD_MARKER[tool]
not in active
271 findings.append(f
"{DOCKERFILE}: {tool} must download to /tmp and verify sha256")
272 if tool
in ARCHIVE_TOOLS
and DOCKER_ARCHIVE_MEMBER[tool]
not in active:
273 findings.append(f
"{DOCKERFILE}: {tool} archive extraction is not file-based/exact")
274 if "hadolint-Linux-" in text:
275 findings.append(f
"{DOCKERFILE}: hadolint asset name has stale uppercase Linux spelling")
279def check_provision(text: str) -> list[str]:
280 """Check native dev-box release installers use the verified helper."""
281 findings: list[str] = []
282 if _unsafe_pipeline(text):
283 findings.append(f
"{PROVISION}: curl output is piped directly to a shell/archive parser")
284 helper = _section(text,
"download_verified()",
"install_shellcheck()")
286 TLS_FLAGS
not in _active(helper)
287 or "-fsSL" not in helper
288 or '-o "${output}"' not in helper
289 or "sha256sum -c -" not in helper
291 findings.append(f
"{PROVISION}: download_verified must fetch to disk and check sha256")
293 block = _section(text, f
"install_{tool}()", PROVISION_END[tool])
294 active = _active(block)
295 if "download_verified" not in block:
296 findings.append(f
"{PROVISION}: install_{tool} bypasses download_verified")
297 if tool
in ARCHIVE_TOOLS
and PROVISION_ARCHIVE_MEMBER[tool]
not in active:
298 findings.append(f
"{PROVISION}: install_{tool} lacks file-based exact extraction")
300 f
"{PROVISION}: canonical Docker ARG {name} is not consumed"
304 if "hadolint-Linux-" in text
or re.search(
r"as_root\s+curl", text):
305 findings.append(f
"{PROVISION}: stale asset spelling or privileged direct download")
309def _check_macos_arm_mapping(text: str) -> list[str]:
310 """Require immutable final host-to-Darwin asset selection."""
311 findings: list[str] = []
312 actual = _section(text,
"arm_toolchain_asset()",
"install_homebrew()")
316 printf '%s\t%s\n' "darwin-arm64" "ARM_GCC_SHA256_DARWIN_ARM64"
319 printf '%s\t%s\n' "darwin-x86_64" "ARM_GCC_SHA256_DARWIN_X86_64"
322 echo "ERROR: unsupported macOS architecture $1 for Arm GNU Toolchain." >&2
327 if _normalise_shell(actual) != _normalise_shell(expected):
328 findings.append(f
"{MAC_SETUP}: Arm asset selector function is not exact")
334 "ARM_GCC_SHA256_X86_64": 1,
335 "ARM_GCC_SHA256_AARCH64": 1,
336 "ARM_GCC_SHA256_DARWIN_X86_64": 2,
337 "ARM_GCC_SHA256_DARWIN_ARM64": 2,
339 if any(text.count(token) != count
for token, count
in expected_counts.items()):
340 findings.append(f
"{MAC_SETUP}: Arm case labels, assets, and hash tokens must be unique")
341 assignment_counts = {
342 name: len(re.findall(rf
"(?m)^\s*{name}=", text))
343 for name
in (
"arm_asset_arch",
"arm_sha_arg",
"arm_sha256")
345 if assignment_counts != {
"arm_asset_arch": 0,
"arm_sha_arg": 0,
"arm_sha256": 1}:
346 findings.append(f
"{MAC_SETUP}: Arm asset/hash variables have an override assignment")
348 "read -r arm_asset_arch arm_sha_arg",
349 'arm_sha256="$(dockerfile_arg "${arm_sha_arg}")"',
350 "readonly arm_asset_arch arm_sha_arg arm_sha256",
353 offsets = tuple(text.find(token)
for token
in order_tokens)
354 if any(offset < 0
for offset
in offsets)
or offsets != tuple(sorted(offsets)):
356 f
"{MAC_SETUP}: Arm asset selection must be final and readonly before URL use"
361def _check_macos_arm_delete(text: str) -> list[str]:
362 """Require a strict release and canonical readonly Arm prefix."""
363 findings: list[str] = []
365 'arm_release="$(dockerfile_arg ARM_GCC_RELEASE)" || exit 1\nreadonly arm_release',
366 r"^[0-9]+\.[0-9]+\.rel[1-9][0-9]*$",
367 'readonly arm_version="${arm_release%.rel*}"',
368 'home_root="$(cd "$HOME" && pwd -P)" || exit 1\nreadonly home_root',
369 'readonly arm_root="${home_root}/opt"',
370 'arm_prefix="$(canonical_cleanup_target '
371 '"${arm_root}/arm-gnu-toolchain-${arm_version}" "$arm_root")" || exit 1\n'
372 "readonly arm_prefix",
373 'if [[ -z "$arm_prefix" ]]',
375 active = _normalise_shell(text)
376 if any(_normalise_shell(token)
not in active
for token
in required):
377 findings.append(f
"{MAC_SETUP}: Arm release/prefix derivation is not strict and readonly")
378 return [*findings, *check_macos_cleanup(text)]
381def _check_macos_arm(text: str, docker: str) -> list[str]:
382 """Check Darwin Arm selection, pin ownership, and deletion safety."""
383 findings = [*_check_macos_arm_mapping(text), *_check_macos_arm_delete(text)]
384 reader = _section(text,
"dockerfile_arg()",
"require_arm_hash_pins()")
385 if _normalise_shell(reader) != _normalise_shell(MAC_DOCKER_ARG_READER):
386 findings.append(f
"{MAC_SETUP}: Docker ARG reader active body is not exact")
387 pin_validator = _section(text,
"require_arm_hash_pins()",
'arm_release="')
389 any(name
not in pin_validator
for name
in ARM_SHA_ARGS)
390 or len(re.findall(
r"(?m)^\s*require_arm_hash_pins\s*$", text)) != 1
392 findings.append(f
"{MAC_SETUP}: bootstrap must validate all four Arm hash pins")
393 expected_url =
"arm-gnu-toolchain-${arm_release}-${arm_asset_arch}-arm-none-eabi.tar.xz"
394 if expected_url
not in text:
395 findings.append(f
"{MAC_SETUP}: Arm URL must include the Darwin asset selector")
396 if TLS_FLAGS
not in _active(_section(text,
'arm_url="',
'echo "[emu-setup] using')):
397 findings.append(f
"{MAC_SETUP}: Arm archive download must enforce HTTPS/TLS")
398 for linux_name, darwin_name
in (
399 (
"ARM_GCC_SHA256_AARCH64",
"ARM_GCC_SHA256_DARWIN_ARM64"),
400 (
"ARM_GCC_SHA256_X86_64",
"ARM_GCC_SHA256_DARWIN_X86_64"),
402 linux_sha = _docker_arg(docker, linux_name)
403 darwin_sha = _docker_arg(docker, darwin_name)
404 if darwin_sha
is not None and darwin_sha == linux_sha:
405 findings.append(f
"{DOCKERFILE}: {darwin_name} must not reuse the Linux archive hash")
409def check_macos(text: str, docker: str) -> list[str]:
410 """Check macOS bootstrap downloads and Darwin Arm archive selection."""
411 findings: list[str] = []
412 commit = _exact_hex_assignment(text,
"homebrew_installer_commit", 40)
413 digest = _exact_hex_assignment(text,
"homebrew_installer_sha256", 64)
414 if commit
is None or digest
is None:
415 findings.append(f
"{MAC_SETUP}: Homebrew installer commit/sha256 pin is missing")
417 "Homebrew/install/${homebrew_installer_commit}/install.sh",
420 "shasum -a 256 -c -",
421 '/bin/bash -p "${installer}"',
423 if any(token
not in text
for token
in required):
424 findings.append(f
"{MAC_SETUP}: Homebrew installer is not download-verify-execute")
425 if "/HEAD/install.sh" in text
or _unsafe_pipeline(text):
426 findings.append(f
"{MAC_SETUP}: mutable or in-memory Homebrew execution is forbidden")
427 return [*findings, *_check_macos_arm(text, docker)]
430def live_findings() -> list[str]:
431 """Return all findings across the three installer ownership surfaces."""
433 *check_dockerfile((ROOT / DOCKERFILE).read_text(encoding=
"utf-8")),
434 *check_provision((ROOT / PROVISION).read_text(encoding=
"utf-8")),
436 (ROOT / MAC_SETUP).read_text(encoding=
"utf-8"),
437 (ROOT / DOCKERFILE).read_text(encoding=
"utf-8"),
442def _arm_pin_mutations(docker: str, name: str) -> tuple[tuple[str, str], ...]:
443 """Return alternate Docker ARG spellings that can override an Arm pin."""
444 alternate =
"99.9.rel1" if name ==
"ARM_GCC_RELEASE" else "0" * 64
446 (docker + f
"\nARG {name}={alternate}\n",
"duplicate"),
447 (docker + f
"\nARG {name}\\\n={alternate}\n",
"continued"),
448 (docker + f
"\nARG UNUSED=ok {name}={alternate}\n",
"multiple-name"),
449 (docker + f
"\nARG {name} {alternate}\n",
"legacy"),
450 (docker + f
"\nARG {name}\\\n# ignored\n={alternate}\n",
"comment continuation"),
452 docker + f
"\nARG {name}\\\n # indented ignored\n={alternate}\n",
453 "indented-comment continuation",
455 (docker + f
"\nARG {name}\\\n\n={alternate}\n",
"empty-line continuation"),
459def _arm_pin_noninstructions(docker: str, name: str) -> tuple[tuple[str, str], ...]:
460 """Return continued non-ARG instructions that contain inert ARG-shaped text."""
461 value = _docker_arg(docker, name)
464 alternate =
"99.9.rel1" if name ==
"ARM_GCC_RELEASE" else "0" * 64
465 canonical = f
"ARG {name}={value}\n"
467 (f
"RUN printf decoy \\\n# ignored\nARG {name}={alternate}\n",
"comment"),
469 f
"RUN printf decoy \\\n # indented ignored\nARG {name}={alternate}\n",
472 (f
"RUN printf decoy \\\n\nARG {name}={alternate}\n",
"empty line"),
475 (docker.replace(canonical, decoy + canonical, 1), label)
for decoy, label
in decoys
479def _docker_arm_selftest(docker: str) -> list[str]:
480 """Return failures from malformed/missing/duplicate Arm pin cases."""
481 failures: list[str] = []
482 release_line =
"ARG ARM_GCC_RELEASE=13.3.rel1"
485 docker.replace(release_line,
"ARG ARM_GCC_RELEASE=../../tmp", 1),
486 "hostile Arm release",
488 (docker +
"\n ARG ARM_GCC_RELEASE=13.3.rel1\n",
"indented duplicate release"),
489 (docker.replace(f
"{release_line}\n",
"", 1),
"missing Arm release"),
491 for mutated, label
in mutations:
492 if not check_dockerfile(mutated):
493 failures.append(f
"Dockerfile {label} must fire")
494 for name
in (
"ARM_GCC_RELEASE", *ARM_SHA_ARGS):
495 value = _docker_arg(docker, name)
497 failures.append(f
"canonical {name} must exist for mutation")
499 for mutated, label
in _arm_pin_mutations(docker, name):
500 if not check_dockerfile(mutated):
501 failures.append(f
"Dockerfile {label} {name} must fire")
502 for mutated, label
in _arm_pin_noninstructions(docker, name):
503 if check_dockerfile(mutated):
504 failures.append(f
"Dockerfile continued RUN {label} {name} must stay quiet")
505 first_hash = ARM_SHA_ARGS[0]
506 first_value = _docker_arg(docker, first_hash)
507 if first_value
and not check_dockerfile(
508 docker.replace(f
"ARG {first_hash}={first_value}\n",
"", 1)
510 failures.append(f
"Dockerfile missing {first_hash} must fire")
514def _macos_arm_selftest(macos: str, docker: str) -> list[str]:
515 """Return failures from Darwin-vs-Linux archive mutation cases."""
516 failures: list[str] = []
518 (macos.replace(
"darwin-arm64",
"aarch64", 1),
"arm64 Linux archive"),
520 macos.replace(
"ARM_GCC_SHA256_DARWIN_ARM64",
"ARM_GCC_SHA256_AARCH64", 1),
523 (macos.replace(
"darwin-x86_64",
"x86_64", 1),
"x86_64 Linux archive"),
525 macos.replace(
"ARM_GCC_SHA256_DARWIN_X86_64",
"ARM_GCC_SHA256_X86_64", 1),
529 for mutated, label
in mutations:
530 if not check_macos(mutated, docker):
531 failures.append(f
"macOS {label} selection must fire")
533 (
"ARM_GCC_SHA256_AARCH64",
"ARM_GCC_SHA256_DARWIN_ARM64",
"arm64"),
534 (
"ARM_GCC_SHA256_X86_64",
"ARM_GCC_SHA256_DARWIN_X86_64",
"x86_64"),
536 for linux_name, darwin_name, label
in pairs:
537 linux_sha = _docker_arg(docker, linux_name)
538 darwin_sha = _docker_arg(docker, darwin_name)
539 if not linux_sha
or not darwin_sha:
540 failures.append(f
"canonical {label} hashes must exist for mutation")
542 if not check_macos(macos, docker.replace(darwin_sha, linux_sha, 1)):
543 failures.append(f
"Darwin {label} duplicate Linux hash pin must fire")
544 branch =
'printf \'%s\\t%s\\n\' "darwin-arm64" "ARM_GCC_SHA256_DARWIN_ARM64"'
545 branch_override = f
'{branch}\n arm_asset_arch="aarch64"'
546 if not check_macos(macos.replace(branch, branch_override, 1), docker):
547 failures.append(
"appended arm64 branch override must fire")
548 readonly_line =
" readonly arm_asset_arch arm_sha_arg arm_sha256"
549 final_override = f
'{readonly_line}\n arm_sha256="{_docker_arg(docker, ARM_SHA_ARGS[0])}"'
550 if not check_macos(macos.replace(readonly_line, final_override, 1), docker):
551 failures.append(
"appended final hash override must fire")
552 dead_case =
""" case "$1" in
554 printf '%s\\t%s\\n' "darwin-arm64" "ARM_GCC_SHA256_DARWIN_ARM64"
557 if not check_macos(macos.replace(
' case "$1" in\n', dead_case, 1), docker):
558 failures.append(
"prepended dead asset case must fire")
562def _macos_parser_safety_mutations(macos: str) -> tuple[tuple[str, str], ...]:
563 """Return hostile parser, hash validation, release, and prefix mutations."""
565 (macos.replace(
"count != 1",
"count < 1", 1),
"duplicate-tolerant ARG parser"),
568 "ARM_GCC_SHA256_X86_64 ARM_GCC_SHA256_AARCH64",
"ARM_GCC_SHA256_AARCH64", 1
570 "incomplete hash-pin validation",
573 macos.replace(
r"^[0-9]+\.[0-9]+\.rel[1-9][0-9]*$",
r"^.*$", 1),
574 "hostile release grammar",
578 'readonly arm_root="${home_root}/opt"',
579 'readonly arm_root="${home_root}"',
582 "prefix outside HOME/opt",
587def _macos_safety_selftest(macos: str, docker: str) -> list[str]:
588 """Return failures from hostile parser, prefix, and deletion mutations."""
590 *_macos_parser_safety_mutations(macos),
591 *macos_cleanup_mutations(macos),
593 failures: list[str] = []
594 for mutated, label
in mutations:
595 if not check_macos(mutated, docker):
596 failures.append(f
"macOS {label} must fire")
600def _run_docker_reader(function: str, docker: str, name: str) -> tuple[bool, str]:
601 """Execute only the extracted Docker ARG reader against an inert fixture."""
602 with tempfile.TemporaryDirectory(prefix=
"ra8-arm-reader-")
as raw:
603 dockerfile = Path(raw) /
"Dockerfile"
604 dockerfile.write_text(docker, encoding=
"utf-8")
605 script = f
'set -u\ndockerfile="$1"\ndockerfile_arg(){function}\ndockerfile_arg "$2"\n'
606 result = subprocess.run(
619 return result.returncode == 0, result.stdout
622def _docker_reader_execution_selftest(macos: str, docker: str) -> list[str]:
623 """Exercise canonical and hostile Docker forms through the macOS reader."""
624 function = _section(macos,
"dockerfile_arg()",
"require_arm_hash_pins()")
625 failures: list[str] = []
626 for name
in (
"ARM_GCC_RELEASE", *ARM_SHA_ARGS):
627 expected = _docker_arg(docker, name)
629 failures.append(f
"canonical {name} must exist for reader execution")
631 accepted, value = _run_docker_reader(function, docker, name)
632 if not accepted
or value != expected:
633 failures.append(f
"macOS reader canonical {name} must stay quiet")
634 for mutated, label
in _arm_pin_mutations(docker, name):
635 accepted, _value = _run_docker_reader(function, mutated, name)
637 failures.append(f
"macOS reader {label} {name} must fire")
638 for mutated, label
in _arm_pin_noninstructions(docker, name):
639 accepted, value = _run_docker_reader(function, mutated, name)
640 if not accepted
or value != expected:
641 failures.append(f
"macOS reader continued RUN {label} {name} must stay quiet")
645def _run_cleanup_validator(function: str, target: str, root: str, cwd: Path) -> tuple[bool, str]:
646 """Run only the canonicalizer; never invoke the recursive removal helper."""
647 script = f
'set -u\ncanonical_cleanup_target(){function}\ncanonical_cleanup_target "$1" "$2"\n'
648 result = subprocess.run(
662 return result.returncode == 0, result.stdout.strip()
665def _cleanup_execution_selftest(macos: str) -> list[str]:
666 """Exercise physical root/target boundaries without deleting anything."""
667 function = _section(macos,
"canonical_cleanup_target()",
"safe_remove_tree()")
668 failures: list[str] = []
669 with tempfile.TemporaryDirectory(prefix=
"ra8-cleanup-guard-")
as raw:
671 safe_root = base /
"safe-root"
673 safe_target = safe_root /
"safe-target"
675 missing_target = safe_root /
"missing-target"
676 missing_root = base /
"missing-root"
677 link_root = base /
"link-root"
678 link_root.symlink_to(safe_root, target_is_directory=
True)
679 link_target = safe_root /
"link-target"
680 link_target.symlink_to(base, target_is_directory=
True)
681 file_target = safe_root /
"file-target"
682 file_target.write_text(
"fixture", encoding=
"ascii")
684 (safe_target, safe_root,
True,
"existing directory"),
685 (missing_target, safe_root,
True,
"missing direct child"),
686 (missing_root /
"child", missing_root,
True,
"missing root under physical parent"),
687 (Path(
"/child"), Path(
"/"),
False,
"root allowed boundary"),
688 (Path(
"relative"), safe_root,
False,
"relative target"),
689 (safe_root, safe_root,
False,
"target equals allowed root"),
690 (link_root /
"child", link_root,
False,
"symlinked allowed root"),
691 (link_target, safe_root,
False,
"symlinked target"),
692 (file_target, safe_root,
False,
"non-directory target"),
694 for target, root, expected, label
in cases:
695 accepted, canonical = _run_cleanup_validator(function, str(target), str(root), base)
696 if accepted != expected
or (accepted
and canonical != str(target)):
697 failures.append(f
"executable cleanup validator case failed: {label}")
701def _macos_privileged_exec_selftest(macos: str, docker: str) -> list[str]:
702 """Require privileged Bash for the downloaded installer."""
705 macos.replace(
'/bin/bash -p "${installer}"',
'/bin/bash "${installer}"', 1),
706 "non-privileged Homebrew installer shell",
709 return [label
for mutated, label
in mutations
if not check_macos(mutated, docker)]
712def _basic_selftest_failures(docker: str, provision: str, macos: str) -> list[str]:
713 """Exercise canonical installer inputs and direct unsafe mutations."""
715 macos +
'\nhomebrew_installer_commit="0000000000000000000000000000000000000000"\n'
718 (bool(check_dockerfile(docker)),
"canonical Dockerfile must stay quiet"),
719 (bool(check_provision(provision)),
"canonical native provisioner must stay quiet"),
720 (bool(check_macos(macos, docker)),
"canonical macOS installer must stay quiet"),
722 not check_dockerfile(docker.replace(DOCKER_VERIFY_MARKER[
"just"],
"sha256sum", 1)),
723 "Dockerfile missing verification must fire",
726 not check_dockerfile(docker.replace(
"--proto-redir '=https'",
"", 1)),
727 "Dockerfile redirect downgrade must fire",
730 not check_dockerfile(docker.replace(DOCKER_ARCHIVE_MEMBER[
"actionlint"],
".", 1)),
731 "Dockerfile unbounded archive extraction must fire",
734 not check_dockerfile(docker +
"\nRUN curl https://example.invalid/x | bash\n"),
735 "Dockerfile curl-to-shell must fire",
738 not check_provision(provision.replace(
"download_verified",
"download_unchecked", 1)),
739 "native provisioner helper bypass must fire",
742 not check_provision(provision.replace(PROVISION_ARCHIVE_MEMBER[
"just"],
".", 1)),
743 "native provisioner unbounded archive extraction must fire",
746 not check_macos(macos.replace(
"${homebrew_installer_commit}",
"HEAD", 1), docker),
747 "mutable Homebrew installer ref must fire",
749 (
not check_macos(duplicate_pin, docker),
"duplicate Homebrew installer commit must fire"),
751 return [label
for failed, label
in cases
if failed]
754def selftest() -> int:
755 """Prove clean live inputs stay quiet and each unsafe direction fires."""
756 docker = (ROOT / DOCKERFILE).read_text(encoding=
"utf-8")
757 provision = (ROOT / PROVISION).read_text(encoding=
"utf-8")
758 macos = (ROOT / MAC_SETUP).read_text(encoding=
"utf-8")
759 failures = _basic_selftest_failures(docker, provision, macos)
761 f
"{label} must fire" for label
in _macos_privileged_exec_selftest(macos, docker)
763 failures.extend(_docker_arm_selftest(docker))
764 failures.extend(_macos_arm_selftest(macos, docker))
765 failures.extend(_macos_safety_selftest(macos, docker))
766 failures.extend(_docker_reader_execution_selftest(macos, docker))
767 failures.extend(_cleanup_execution_selftest(macos))
769 print(
"check_download_installers.py --selftest: FAIL", file=sys.stderr)
770 for failure
in failures:
771 print(f
" {failure}", file=sys.stderr)
773 print(
"check_download_installers.py --selftest: PASS (222 both-direction cases)")
778 """Run selftests or the live installer policy audit."""
779 parser = argparse.ArgumentParser()
780 parser.add_argument(
"--selftest", action=
"store_true")
781 args = parser.parse_args()
784 findings = live_findings()
786 print(
"\n".join(findings), file=sys.stderr)
788 print(
"check_download_installers.py: pinned download/verify/install flows are intact")
792if __name__ ==
"__main__":
void main(void)
The application entry point Reset_Handler hands control to.