ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
python_lock_policy_uv_execution.py
Go to the documentation of this file.
1# SPDX-License-Identifier: MIT
2# Copyright (c) 2026 Brighton Sikarskie
3"""Semantic policy for immutable uv execution and lock-policy consumers."""
4
5from __future__ import annotations
6
7import ast
8import hashlib
9from pathlib import Path
10
11DEPLOYMENT_CLOSURE_PATHS = (
12 Path(".devcontainer/Dockerfile"),
13 Path(".dockerignore"),
14 Path("infra/ansible/roles/ci_runner/tasks/main.yml"),
15 Path("infra/ansible/roles/dev_box/tasks/transaction.yml"),
16 Path("infra/ansible/roles/hil_bench/tasks/transaction.yml"),
17 Path("scripts/ci/devcontainer_image.sh"),
18 Path("scripts/dev/fleet_wsl.py"),
19 Path("scripts/dev/fleet_wsl_stage.py"),
20)
21EXEC_MODULE_SHA256 = "bd54ee9be90ca047c535349b2ab3855b4afcefd53c077a56215f5440d76e2ae4"
22RUNNER_MODULE_SHA256 = "4242262cf1649cf5935dd8e12f42b737bbc2592b3d633615acf6593179502f40"
23EXEC_EXACT_BODIES = {
24 "_open_parent_fd": """
25def _open_parent_fd(path, *, create=False):
26 nofollow = getattr(os, "O_NOFOLLOW", None)
27 cloexec = getattr(os, "O_CLOEXEC", None)
28 directory = getattr(os, "O_DIRECTORY", None)
29 if nofollow is None or cloexec is None or directory is None:
30 fail("POSIX uv cache access requires O_NOFOLLOW, O_CLOEXEC, and O_DIRECTORY")
31 if not path.is_absolute() or path.name in ("", ".", ".."):
32 fail(f"uv cache artifact path is not an absolute file path: {path}")
33 components = path.parent.parts[1:]
34 if len(components) > MAX_CACHE_PATH_COMPONENTS:
35 fail(f"uv cache artifact path has too many components: {path}")
36 flags = os.O_RDONLY | nofollow | cloexec | directory
37 descriptor = -1
38 try:
39 descriptor = os.open(path.anchor, flags)
40 root_descriptor = descriptor
41 descriptor = -1
42 descriptor = open_parent_components(
43 root_descriptor,
44 components,
45 flags,
46 create=create,
47 platform_name=sys.platform,
48 )
49 except (OSError, NotImplementedError, TypeError) as exc:
50 if descriptor >= 0:
51 os.close(descriptor)
52 fail(f"cannot open cached uv parent {path.parent}: {exc}")
53 return descriptor
54""",
55 "open_parent_components": """
56def open_parent_components(descriptor, components, flags, *, create, platform_name):
57 try:
58 for index, component in enumerate(components):
59 try:
60 next_descriptor = -1
61 alias_key = index, platform_name, component
62 if alias_key in DARWIN_ROOT_ALIAS_POSITIONS:
63 _require_trusted_system_root(descriptor)
64 next_descriptor = _open_verified_darwin_alias(descriptor, component, flags)
65 if next_descriptor < 0:
66 next_descriptor = os.open(component, flags, dir_fd=descriptor)
67 except FileNotFoundError:
68 if not create:
69 raise
70 with suppress(FileExistsError):
71 os.mkdir(component, CACHE_DIRECTORY_MODE, dir_fd=descriptor)
72 next_descriptor = os.open(component, flags, dir_fd=descriptor)
73 previous = descriptor
74 descriptor = next_descriptor
75 os.close(previous)
76 except Exception:
77 os.close(descriptor)
78 raise
79 return descriptor
80""",
81 "_open_verified_darwin_alias": """
82def _open_verified_darwin_alias(root_descriptor, component, flags):
83 target = DARWIN_ROOT_ALIASES.get(component)
84 if target is None:
85 fail(f"unsupported Darwin uv cache root alias: {component}")
86 expected = "/".join(target)
87 before = os.stat(component, dir_fd=root_descriptor, follow_symlinks=False)
88 before_target = os.readlink(component, dir_fd=root_descriptor)
89 if not stat.S_ISLNK(before.st_mode):
90 fail(f"Darwin uv cache root alias is not a symlink: /{component}")
91 if before.st_uid != 0:
92 fail(f"Darwin uv cache root alias is not root-owned: /{component}")
93 if before_target != expected:
94 fail(f"untrusted Darwin uv cache root alias: /{component}")
95 alias_descriptor = -1
96 physical_descriptor = -1
97 succeeded = False
98 try:
99 alias_descriptor = os.open(
100 component,
101 flags & ~os.O_NOFOLLOW,
102 dir_fd=root_descriptor,
103 )
104 physical_descriptor = _open_physical_alias_target(root_descriptor, target, flags)
105 alias_state = os.fstat(alias_descriptor)
106 physical_state = os.fstat(physical_descriptor)
107 after = os.stat(component, dir_fd=root_descriptor, follow_symlinks=False)
108 after_target = os.readlink(component, dir_fd=root_descriptor)
109 if not stat.S_ISDIR(alias_state.st_mode):
110 fail(f"Darwin uv cache alias target is not a directory: /{component}")
111 if not stat.S_ISDIR(physical_state.st_mode):
112 fail(f"Darwin uv cache physical target is not a directory: /{component}")
113 if _stat_identity(alias_state) != _stat_identity(physical_state):
114 fail(f"Darwin uv cache root alias target mismatched: /{component}")
115 if _link_fingerprint(before) != _link_fingerprint(after):
116 fail(f"Darwin uv cache root alias changed identity: /{component}")
117 if after_target != expected:
118 fail(f"Darwin uv cache root alias changed target: /{component}")
119 succeeded = True
120 finally:
121 if alias_descriptor >= 0:
122 os.close(alias_descriptor)
123 if not succeeded and physical_descriptor >= 0:
124 os.close(physical_descriptor)
125 return physical_descriptor
126""",
127 "_new_temporary_fd": """
128def _new_temporary_fd(parent, mode=PRIVATE_TEMPORARY_FILE_MODE):
129 cloexec = getattr(os, "O_CLOEXEC", None)
130 nofollow = getattr(os, "O_NOFOLLOW", None)
131 if cloexec is None or nofollow is None:
132 fail("POSIX uv cache writes require O_CLOEXEC and O_NOFOLLOW")
133 if mode not in (PROBE_EXECUTABLE_MODE, PRIVATE_TEMPORARY_FILE_MODE):
134 fail("POSIX uv cache temporary mode is outside policy")
135 flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL | cloexec | nofollow
136 for _attempt in range(MAX_TEMPORARY_NAME_ATTEMPTS):
137 name = f".ra8-uv-{secrets.token_hex(16)}.tmp"
138 try:
139 return os.open(name, flags, mode, dir_fd=parent), name
140 except FileExistsError:
141 continue
142 fail("cannot allocate a private uv cache temporary")
143""",
144 "write_atomic_nofollow": """
145def write_atomic_nofollow(path, payload, mode):
146 if not payload or mode not in (0o600, 0o700):
147 fail("uv cache write requires nonempty bytes and one private mode")
148 parent = _open_parent_fd(path, create=True)
149 descriptor = -1
150 temporary = ""
151 try:
152 descriptor, temporary = _new_temporary_fd(parent)
153 write_exact_fd(descriptor, payload)
154 os.fsync(descriptor)
155 os.fchmod(descriptor, mode)
156 os.replace(temporary, path.name, src_dir_fd=parent, dst_dir_fd=parent)
157 except (OSError, NotImplementedError, TypeError) as exc:
158 fail(f"cannot write cached uv artifact {path}: {exc}")
159 finally:
160 if descriptor >= 0:
161 os.close(descriptor)
162 if temporary:
163 with suppress(FileNotFoundError):
164 os.unlink(temporary, dir_fd=parent)
165 os.close(parent)
166""",
167 "open_regular_nofollow": """
168def open_regular_nofollow(path):
169 nonblock = getattr(os, "O_NONBLOCK", None)
170 cloexec = getattr(os, "O_CLOEXEC", None)
171 nofollow = getattr(os, "O_NOFOLLOW", None)
172 if nonblock is None or cloexec is None or nofollow is None:
173 fail("POSIX uv cache access requires O_NONBLOCK, O_CLOEXEC, and O_NOFOLLOW")
174 parent = _open_parent_fd(path)
175 descriptor = -1
176 try:
177 descriptor = os.open(
178 path.name,
179 os.O_RDONLY | nonblock | cloexec | nofollow,
180 dir_fd=parent,
181 )
182 state = os.fstat(descriptor)
183 except OSError as exc:
184 if descriptor >= 0:
185 os.close(descriptor)
186 fail(f"cannot open cached uv artifact {path}: {exc}")
187 finally:
188 os.close(parent)
189 if not stat.S_ISREG(state.st_mode) or state.st_nlink != 1:
190 os.close(descriptor)
191 fail(f"cached uv artifact is not one single-link regular file: {path}")
192 return descriptor
193""",
194 "portable_named_exec_snapshot": """
195def portable_named_exec_snapshot(binary):
196 if not binary:
197 fail("authenticated uv executable bytes are empty")
198 reader = -1
199 writer = -1
200 parent = -1
201 temporary = ""
202 identity = (-1, -1)
203 try:
204 with tempfile.TemporaryDirectory(prefix="ra8-uv-probe-") as raw:
205 probe_path = Path(raw) / "probe"
206 parent = _open_parent_fd(probe_path)
207 _require_private_temporary_parent(parent)
208 writer, temporary = _new_temporary_fd(parent, PROBE_EXECUTABLE_MODE)
209 write_exact_fd(writer, binary)
210 os.fsync(writer)
211 os.fchmod(writer, PROBE_EXECUTABLE_MODE)
212 writer_state = os.fstat(writer)
213 identity = _stat_identity(writer_state)
214 flags = os.O_RDONLY | os.O_NONBLOCK | os.O_CLOEXEC | os.O_NOFOLLOW
215 reader = os.open(temporary, flags, dir_fd=parent)
216 if _stat_identity(os.fstat(reader)) != identity:
217 fail("authenticated uv reader did not reopen the staged inode")
218 os.close(writer)
219 writer = -1
220 _verify_portable_exec_fd(reader, binary, identity, linked=True)
221 _verify_portable_exec_name(parent, temporary, binary, identity)
222 try:
223 yield reader, str(Path(raw) / temporary)
224 finally:
225 _verify_portable_exec_fd(reader, binary, identity, linked=True)
226 _verify_portable_exec_name(parent, temporary, binary, identity)
227 _unlink_matching_temporary(parent, temporary, identity, required=True)
228 os.fsync(parent)
229 temporary = ""
230 _verify_portable_exec_fd(reader, binary, identity, linked=False)
231 except (OSError, NotImplementedError, TypeError) as exc:
232 fail(f"cannot stage portable authenticated uv executable: {exc}")
233 finally:
234 if writer >= 0:
235 os.close(writer)
236 if temporary and parent >= 0:
237 with suppress(OSError):
238 _unlink_matching_temporary(
239 parent,
240 temporary,
241 identity,
242 required=False,
243 )
244 if parent >= 0:
245 os.close(parent)
246 if reader >= 0:
247 os.close(reader)
248""",
249}
250EXEC_EXACT_FUNCTION_DIGESTS = {
251 "_stat_identity": "a81b93626d87198239f1124ed99fab850e5eb4295fb82106e634033b64ebf516",
252 "_link_fingerprint": "04c45b309f6f2012d9279e0394eff98ee65ef3881a9250a8f878cf7514ad0912",
253 "_require_trusted_system_root": (
254 "6cbfe9fd647e6deffbc970ebda15e88657ee2ca7648ec8fc5c40fa3befc1aed8"
255 ),
256 "_open_physical_alias_target": (
257 "b7fc16104dc3b324b7c313966e1cad9af64f67a0b98f5b4bd8f58cd7dbdb9b62"
258 ),
259 "_verify_portable_exec_fd": (
260 "41a9b81da3e1f72f62c9b89a5a94b059e92bab07da4994b8c837dad7ee564c82"
261 ),
262 "_unlink_matching_temporary": (
263 "d4c1fbdc7a416521f30b9ca59f2d538587360a90f4bd50829342fdf279a88d52"
264 ),
265 "_require_private_temporary_parent": (
266 "4c7252aa77a5879330b6609383b8375f594537ce87069410160bfc5b9847ddc1"
267 ),
268 "_verify_portable_exec_name": (
269 "442b996daeaa03955af307ce0eca050adeee4ec0ef8c1adf9eb69842c487a6be"
270 ),
271 "linux_sealed_exec_fd": ("9a989bab6c3b2da394f1efa83b57ba96d5331b68f8df4de3252f898da56a4ef6"),
272 "authenticated_executable_fd": (
273 "7b2881c38c36e46545428ab2471f03f5e4bde59f71477eb898ea622f54dd7087"
274 ),
275 "run_uv_snapshot": "94c875cfa5a0c0d4571e999b296b6bd5adf71ae9344b6ed5dfe6e10ad250d07e",
276}
277EXEC_EXACT_ASSIGNMENTS = {
278 "PROBE_EXECUTABLE_MODE": "320",
279 "PRIVATE_TEMPORARY_DIRECTORY_MODE": "448",
280 "PRIVATE_TEMPORARY_FILE_MODE": "384",
281 "DARWIN_ROOT_ALIASES": ("{'tmp': ('private', 'tmp'), 'var': ('private', 'var')}"),
282 "DARWIN_ROOT_ALIAS_POSITIONS": (
283 "frozenset((0, 'darwin', component) for component in DARWIN_ROOT_ALIASES)"
284 ),
285}
286EXEC_CALL_CONTRACTS = {
287 "linux_sealed_exec_fd": (
288 ("os", "memfd_create", 1),
289 ("", "write_exact_fd", 1),
290 ("os", "fchmod", 1),
291 ("seals", "fcntl", 2),
292 ),
293 "portable_named_exec_snapshot": (
294 ("tempfile", "TemporaryDirectory", 1),
295 ("", "_open_parent_fd", 1),
296 ("", "_require_private_temporary_parent", 1),
297 ("", "_new_temporary_fd", 1),
298 ("", "write_exact_fd", 1),
299 ("os", "fsync", 2),
300 ("os", "fchmod", 1),
301 ("os", "open", 1),
302 ("", "_verify_portable_exec_fd", 3),
303 ("", "_verify_portable_exec_name", 2),
304 ("", "_unlink_matching_temporary", 2),
305 ),
306 "authenticated_executable_fd": (
307 ("", "linux_sealed_exec_fd", 1),
308 ("", "portable_named_exec_snapshot", 1),
309 ("", "executable_fd_path", 1),
310 ("os", "close", 1),
311 ),
312 "run_uv_snapshot": (
313 ("", "authenticated_executable_fd", 1),
314 ("subprocess", "run", 1),
315 ),
316}
317EXEC_MUTATIONS = (
318 (
319 ' fail(f"authenticated uv execution failed: {exc}")\n',
320 ' fail(f"authenticated uv execution failed: {exc}")\n'
321 "_uv_alias_escape = DARWIN_ROOT_ALIASES\n"
322 '_uv_alias_escape["etc"] = ("private", "etc")\n'
323 'globals()["DARWIN_ROOT_ALIAS_POSITIONS"] = frozenset(\n'
324 ' (0, "darwin", component) for component in _uv_alias_escape\n'
325 ")\n",
326 ),
327 (
328 ' fail(f"authenticated uv execution failed: {exc}")\n',
329 ' fail(f"authenticated uv execution failed: {exc}")\n'
330 "UV_EXEC_UNREVIEWED_SURFACE = True\n",
331 ),
332 (
333 "def _require_trusted_system_root(descriptor: int) -> None:\n",
334 "@staticmethod\ndef _require_trusted_system_root(descriptor: int) -> None:\n",
335 ),
336 (" held = os.fstat(descriptor)\n", " return\n"),
337 (
338 "def _require_private_temporary_parent(descriptor: int) -> None:\n"
339 ' """Require the held portable-snapshot directory to be caller-private."""\n'
340 " state = os.fstat(descriptor)\n",
341 "def _require_private_temporary_parent(descriptor: int) -> None:\n"
342 ' """Require the held portable-snapshot directory to be caller-private."""\n'
343 " return\n",
344 ),
345 (
346 ' "tmp": ("private", "tmp"),\n',
347 ' "etc": ("private", "etc"),\n "tmp": ("private", "tmp"),\n',
348 ),
349 (" if held.st_uid != 0:\n", " if False:\n"),
350 (" if state.st_uid != os.geteuid():\n", " if False:\n"),
351 (
352 " [executable, *arguments],\n",
353 " [str(Path('/tmp/uv')), *arguments],\n",
354 ),
355 (
356 " if next_descriptor < 0:\n"
357 " next_descriptor = os.open(component, flags, dir_fd=descriptor)\n"
358 " except FileNotFoundError:\n",
359 " if next_descriptor < 0:\n"
360 " next_descriptor = os.open(component, flags)\n"
361 " except FileNotFoundError:\n",
362 ),
363 (
364 " reader = os.open(temporary, flags, dir_fd=parent)\n",
365 " reader = os.open(temporary, flags)\n",
366 ),
367 (
368 "flags = os.O_RDONLY | nofollow | cloexec | directory",
369 "flags = os.O_RDONLY | nofollow | cloexec",
370 ),
371 (
372 "parent = _open_parent_fd(path, create=True)",
373 "parent = _open_parent_fd(path)",
374 ),
375 (
376 "os.replace(temporary, path.name, src_dir_fd=parent, dst_dir_fd=parent)",
377 "os.replace(temporary, path.name)",
378 ),
379 ("seals.fcntl(descriptor, seals.F_ADD_SEALS, mask)", "pass"),
380 (" pass_fds=(descriptor,),\n", ""),
381 (
382 " _require_private_temporary_parent(parent)\n",
383 " pass\n",
384 ),
385 (
386 " _verify_portable_exec_name(parent, temporary, binary, identity)\n"
387 " try:\n",
388 " try:\n",
389 ),
390 (
391 " _unlink_matching_temporary(parent, temporary, identity, required=True)\n",
392 " os.unlink(temporary, dir_fd=parent)\n",
393 ),
394)
395RUNNER_MUTATION_ANCHOR = (
396 " failures.append("
397 'f"post-auth {mode} replacement executed through lock/export")\n'
398 " return failures\n"
399)
400RUNNER_MUTATIONS = (
401 (
402 RUNNER_MUTATION_ANCHOR,
403 RUNNER_MUTATION_ANCHOR + "AuthenticatedUv.run = lambda self, arguments, **kwargs: None\n",
404 ),
405 (
406 RUNNER_MUTATION_ANCHOR,
407 RUNNER_MUTATION_ANCHOR + "find_uv = lambda *_args, **_kwargs: None\n",
408 ),
409 (
410 RUNNER_MUTATION_ANCHOR,
411 RUNNER_MUTATION_ANCHOR + "UV_RUNNER_UNREVIEWED_SURFACE = True\n",
412 ),
413 (' "--run",\n', ' "--verify-cache",\n'),
414 ('probe = candidate.run(["--version"], timeout=10)', "probe = None"),
415 ("lock_check = uv.run(\n", "lock_check = subprocess.run(\n"),
416 (
417 ' \'mv "$RA8_UV_ATTACK_CACHE" "$RA8_UV_ATTACK_CACHE.displaced"\\n\'\n',
418 "",
419 ),
420)
421
422
423def _function(tree: ast.AST, name: str) -> ast.FunctionDef | None:
424 """Return one unambiguous function anywhere in a module."""
425 matches = [
426 node for node in ast.walk(tree) if isinstance(node, ast.FunctionDef) and node.name == name
427 ]
428 return matches[0] if len(matches) == 1 else None
429
430
431def _body_dump(function: ast.FunctionDef) -> str:
432 """Return one function body without its documentation literal."""
433 body = list(function.body)
434 if (
435 body
436 and isinstance(body[0], ast.Expr)
437 and isinstance(body[0].value, ast.Constant)
438 and isinstance(body[0].value.value, str)
439 ):
440 body = body[1:]
441 return ast.dump(ast.Module(body=body, type_ignores=[]), include_attributes=False)
442
443
444def _exact_function_digest_finding(
445 source: str, tree: ast.Module, name: str, expected: str
446) -> list[str]:
447 """Bind one complete security function, including signature and decorators."""
448 function = _function(tree, name)
449 if function is None:
450 return [f"uv execution {name} complete semantic contract drifted"]
451 lines = source.splitlines(keepends=True)
452 starts = [function.lineno, *(item.lineno for item in function.decorator_list)]
453 segment = "".join(lines[min(starts) - 1 : function.end_lineno]).rstrip("\r\n")
454 actual = hashlib.sha256(segment.encode()).hexdigest()
455 if actual != expected:
456 return [f"uv execution {name} complete semantic contract drifted"]
457 return []
458
459
460def _assignment_value(tree: ast.Module, name: str) -> ast.AST | None:
461 """Return the sole top-level value assigned to one execution authority."""
462 values = []
463 for statement in tree.body:
464 if not isinstance(statement, ast.Assign) or len(statement.targets) != 1:
465 continue
466 if isinstance(statement.targets[0], ast.Name) and statement.targets[0].id == name:
467 values.append(statement.value)
468 return values[0] if len(values) == 1 else None
469
470
471def _authority_assignment_findings(tree: ast.Module) -> list[str]:
472 """Bind Darwin aliases/modes and reject all later authority mutation."""
473 findings = []
474 for name, expression in EXEC_EXACT_ASSIGNMENTS.items():
475 expected = ast.parse(expression, mode="eval").body
476 actual = _assignment_value(tree, name)
477 if actual is None or ast.dump(actual) != ast.dump(expected):
478 findings.append(f"uv execution authority assignment drifted: {name}")
479 protected = set(EXEC_EXACT_ASSIGNMENTS)
480 for node in ast.walk(tree):
481 if (
482 isinstance(node, ast.Call)
483 and isinstance(node.func, ast.Attribute)
484 and isinstance(node.func.value, ast.Name)
485 and node.func.value.id in protected
486 and node.func.attr != "get"
487 ):
488 findings.append(f"uv execution authority mutation attempted: {node.func.value.id}")
489 if isinstance(node, (ast.Subscript, ast.Attribute)) and isinstance(
490 node.ctx, (ast.Store, ast.Del)
491 ):
492 root = node.value
493 while isinstance(root, (ast.Subscript, ast.Attribute)):
494 root = root.value
495 if isinstance(root, ast.Name) and root.id in protected:
496 findings.append(f"uv execution authority mutation attempted: {root.id}")
497 return findings
498
499
500def _exact_body_finding(tree: ast.Module, name: str, expected: str) -> list[str]:
501 """Bind one security-critical function to its reviewed semantic body."""
502 function = _function(tree, name)
503 fixture = _function(ast.parse(expected), name)
504 if function is None or fixture is None or _body_dump(function) != _body_dump(fixture):
505 return [f"uv execution {name} semantic contract drifted"]
506 return []
507
508
509def _call_count(function: ast.FunctionDef, owner: str, name: str) -> int:
510 """Count exact direct-name or one-level qualified calls in a function."""
511 count = 0
512 for node in ast.walk(function):
513 if not isinstance(node, ast.Call):
514 continue
515 if not owner and isinstance(node.func, ast.Name) and node.func.id == name:
516 count += 1
517 if (
518 owner
519 and isinstance(node.func, ast.Attribute)
520 and isinstance(node.func.value, ast.Name)
521 and node.func.value.id == owner
522 and node.func.attr == name
523 ):
524 count += 1
525 return count
526
527
528def _required_calls(
529 tree: ast.Module,
530 function_name: str,
531 required: tuple[tuple[str, str, int], ...],
532) -> list[str]:
533 """Report a missing function or any exact call-count drift."""
534 function = _function(tree, function_name)
535 if function is None:
536 return [f"uv execution function is missing or ambiguous: {function_name}"]
537 return [
538 f"uv execution {function_name} {owner}.{name} call chain drifted"
539 for owner, name, expected in required
540 if _call_count(function, owner, name) != expected
541 ]
542
543
544def _keyword_value(function: ast.FunctionDef, call_owner: str, keyword: str) -> ast.AST | None:
545 """Return one keyword value from one qualified call, rejecting ambiguity."""
546 values = []
547 for node in ast.walk(function):
548 if not isinstance(node, ast.Call) or not isinstance(node.func, ast.Attribute):
549 continue
550 if not isinstance(node.func.value, ast.Name) or node.func.value.id != call_owner:
551 continue
552 values.extend(item.value for item in node.keywords if item.arg == keyword)
553 return values[0] if len(values) == 1 else None
554
555
556def _exec_call_findings(tree: ast.Module) -> list[str]:
557 """Bind immutable execution call chains and descriptor inheritance."""
558 findings = []
559 for name, required in EXEC_CALL_CONTRACTS.items():
560 findings.extend(_required_calls(tree, name, required))
561 runner = _function(tree, "run_uv_snapshot")
562 pass_fds = None if runner is None else _keyword_value(runner, "subprocess", "pass_fds")
563 if not (
564 isinstance(pass_fds, ast.Tuple)
565 and len(pass_fds.elts) == 1
566 and isinstance(pass_fds.elts[0], ast.Name)
567 and pass_fds.elts[0].id == "descriptor"
568 ):
569 findings.append("uv execution subprocess is not bound to the immutable descriptor")
570 return findings
571
572
573def exec_module_findings(source: str) -> list[str]:
574 """Bind sealed/read-only descriptor creation and subprocess inheritance."""
575 identity_findings = (
576 []
577 if hashlib.sha256(source.encode()).hexdigest() == EXEC_MODULE_SHA256
578 else ["uv execution module byte identity drifted"]
579 )
580 try:
581 tree = ast.parse(source)
582 except SyntaxError as exc:
583 return [f"uv execution module is invalid Python: {exc}"]
584 findings = [
585 finding
586 for name, expected in EXEC_EXACT_BODIES.items()
587 for finding in _exact_body_finding(tree, name, expected)
588 ]
589 findings.extend(
590 finding
591 for name, expected in EXEC_EXACT_FUNCTION_DIGESTS.items()
592 for finding in _exact_function_digest_finding(source, tree, name, expected)
593 )
594 return [
595 *identity_findings,
596 *findings,
597 *_authority_assignment_findings(tree),
598 *_exec_call_findings(tree),
599 ]
600
601
602def runner_module_findings(source: str) -> list[str]:
603 """Bind lock/export work to bootstrap --run instead of a returned path."""
604 identity_findings = (
605 []
606 if hashlib.sha256(source.encode()).hexdigest() == RUNNER_MODULE_SHA256
607 else ["lock-policy uv runner module byte identity drifted"]
608 )
609 try:
610 tree = ast.parse(source)
611 except SyntaxError as exc:
612 return [f"uv runner module is invalid Python: {exc}"]
613 findings = [*identity_findings, *_required_calls(tree, "run", (("subprocess", "run", 1),))]
614 findings.extend(_required_calls(tree, "find_uv", (("candidate", "run", 1),)))
615 findings.extend(_required_calls(tree, "export_findings", (("uv", "run", 1),)))
616 findings.extend(_required_calls(tree, "_one_export_findings", (("uv", "run", 1),)))
617 run = _function(tree, "run")
618 if run is None:
619 return findings
620 literals = {
621 node.value
622 for node in ast.walk(run)
623 if isinstance(node, ast.Constant) and isinstance(node.value, str)
624 }
625 if not {"/usr/bin/python3", "-I", "-S", "--manifest", "--cache-root", "--run"}.issubset(
626 literals
627 ):
628 findings.append("lock-policy uv runner no longer uses the exact bootstrap --run boundary")
629 if "str(candidate)" in source or "str(uv)" in source:
630 findings.append("lock-policy uv runner executes a returned mutable cache path")
631 rename_old = 'mv "$RA8_UV_ATTACK_CACHE" "$RA8_UV_ATTACK_CACHE.displaced"'
632 move_replacement = 'mv "$RA8_UV_ATTACK_REPLACEMENT" "$RA8_UV_ATTACK_CACHE"'
633 if rename_old not in source or move_replacement not in source:
634 findings.append("lock-policy path attack does not preserve the authenticated inode link")
635 return findings
636
637
638def uv_execution_policy_findings(root: Path) -> list[str]:
639 """Return immutable-execution findings for both production modules."""
640 exec_source = (root / "scripts/dev/bootstrap_uv_exec.py").read_text(encoding="utf-8")
641 runner_source = (root / "scripts/checks/python_lock_policy_uv_runner.py").read_text(
642 encoding="utf-8"
643 )
644 return [
645 *exec_module_findings(exec_source),
646 *runner_module_findings(runner_source),
647 *deployment_closure_findings(root),
648 ]
649
650
651def deployment_closure_findings(root: Path) -> list[str]:
652 """Require every staged bootstrap deployment to carry its exec helper."""
653 findings: list[str] = []
654 for relative in DEPLOYMENT_CLOSURE_PATHS:
655 source = (root / relative).read_text(encoding="utf-8")
656 has_bootstrap = "bootstrap_uv.py" in source
657 has_helper = "bootstrap_uv_exec.py" in source
658 if has_bootstrap != has_helper:
659 findings.append(f"{relative}: uv bootstrap/exec-helper deployment closure drifted")
660 return findings
661
662
663def _mutate_once(source: str, old: str, new: str) -> str:
664 """Return one exact mutation, rejecting a stale selftest anchor."""
665 if source.count(old) != 1:
666 message = f"uv execution mutation anchor count drifted: {old!r}"
667 raise ValueError(message)
668 return source.replace(old, new, 1)
669
670
671def uv_execution_policy_selftest(root: Path) -> list[str]:
672 """Prove each immutable-execution and consumer boundary fires."""
673 exec_source = (root / "scripts/dev/bootstrap_uv_exec.py").read_text(encoding="utf-8")
674 runner_source = (root / "scripts/checks/python_lock_policy_uv_runner.py").read_text(
675 encoding="utf-8"
676 )
677 failures = ["live uv execution policy failed"] if uv_execution_policy_findings(root) else []
678 failures.extend(
679 f"uv execution mutation passed: {old}"
680 for old, new in EXEC_MUTATIONS
681 if not exec_module_findings(_mutate_once(exec_source, old, new))
682 )
683 failures.extend(
684 f"uv runner mutation passed: {old}"
685 for old, new in RUNNER_MUTATIONS
686 if not runner_module_findings(_mutate_once(runner_source, old, new))
687 )
688 with_helper = "COPY bootstrap_uv.py bootstrap_uv_exec.py /trusted/"
689 fixture = dict.fromkeys(DEPLOYMENT_CLOSURE_PATHS, with_helper)
690 if _deployment_fixture_findings(fixture):
691 failures.append("complete uv deployment fixture failed")
692 first = DEPLOYMENT_CLOSURE_PATHS[0]
693 fixture[first] = "COPY bootstrap_uv.py /trusted/"
694 if not _deployment_fixture_findings(fixture):
695 failures.append("bootstrap deployment without exec helper passed")
696 fixture[first] = "COPY bootstrap_uv_exec.py /trusted/"
697 if not _deployment_fixture_findings(fixture):
698 failures.append("orphan uv exec-helper deployment passed")
699 return failures
700
701
702def _deployment_fixture_findings(documents: dict[Path, str]) -> list[str]:
703 """Return bootstrap/helper closure findings for synthetic documents."""
704 return [
705 str(relative)
706 for relative, source in documents.items()
707 if ("bootstrap_uv.py" in source) != ("bootstrap_uv_exec.py" in source)
708 ]
#define min(x, y)
Untyped minimum shim used by the SOUP's buffer clamping.
Definition xz_config.h:157