3"""Scoped process-authority policy for devcontainer image selftests."""
5from __future__
import annotations
7PROCESS_MODULE_SEMANTIC_TOKENS = {
8 "entry descriptor floor lowered into helper range":
"ENTRY_EXEC_DESCRIPTOR_MINIMUM = 64",
11SUPERVISOR_SEMANTIC_PROCESS_TOKENS = {
12 "bound-exit supervisor pre-spawn signal block removed": (
13 "old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, MANAGED_SIGNALS)"
15 "bound-exit parent-death pipe removed": (
16 "self.death_read, self.death_write = os.pipe2(os.O_CLOEXEC)"
18 "bound-exit parent-death descriptor propagation removed": (
19 "inherited = [source_descriptor, self.death_read, root_descriptor]"
21 "bound-exit controller interpreter changed":
" sys.executable,",
22 "bound-exit controller no-bytecode isolation removed":
' "-B",',
23 "bound-exit controller isolated-mode flag removed":
' "-I",',
24 "bound-exit controller site-import refusal removed":
' "-S",',
25 "bound-exit controller immutable helper path removed": (
26 ' __file__,\n "--controller",'
28 "bound-exit payload fixed Bash path removed":
' "/bin/bash",',
29 "bound-exit payload protected Bash mode removed":
' "-p",',
30 "bound-exit parent-death polling removed": (
31 "ready, _, _ = select.select((death_descriptor,), (), (), POLL_SECONDS)"
33 "bound-exit payload signal reset removed": (
34 " _reset_managed_signals()\n"
36 " os.execl( # noqa: S606 -- fixed Bash and descriptor-bound entry"
38 "controller close failure bypasses group KILL": (
39 "for private_descriptor in (death_descriptor, root_descriptor):\n"
40 " with suppress(OSError):\n"
41 " os.close(private_descriptor)\n"
42 " os.killpg(os.getpgrp(), signal.SIGKILL)"
44 "bound-exit controller group cleanup reduced to controller PID": (
45 "for private_descriptor in (death_descriptor, root_descriptor):\n"
46 " with suppress(OSError):\n"
47 " os.close(private_descriptor)\n"
48 " os.killpg(os.getpgrp(), signal.SIGKILL)"
50 "bound-exit terminal payload is polled after reap": (
51 " if not published:\n child_status = _poll_payload(child)"
53 "bound-exit controller liveness proof removed": (
54 ' supervisor.require_running("after publishing status")'
56 "bound receipt hardlink refusal removed":
" or metadata.st_nlink != 1",
57 "bound receipt owner binding removed":
" or metadata.st_uid != os.getuid()",
58 "bound receipt mode binding removed": (
59 " or stat.S_IMODE(metadata.st_mode) != RECEIPT_MODE"
61 "bound receipt truncation removed":
" os.ftruncate(descriptor, 0)",
62 "receipt exact-write helper definition removed":
"def _write_exact(",
63 "exclusive receipt exact-write use removed": (
64 " _write_exact(descriptor, payload, ENTRY_MAX_BYTES)"
66 "bound receipt exact-write use removed": (
67 " _write_exact(descriptor, payload, RECEIPT_MAX_BYTES)"
69 "status receipt no-follow descriptor removed": (
70 " descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)"
72 "process stat bytes parser replaced with text decoding":
'(entry / "stat").read_bytes()',
73 "bound-exit group cleanup reduced to leader PID":
"os.killpg(leader, signal.SIGKILL)",
74 "bound-exit cleanup signal block moved after authority checks": (
75 " signal.pthread_sigmask(signal.SIG_BLOCK, MANAGED_SIGNALS)\n"
76 " if self.pid is None or self.reaped:"
78 "bound-exit status atomic publication removed": (
79 "os.link(temporary, path, follow_symlinks=False)"
81 "missing payload exec status weakened":
" except OSError:\n os._exit(127)",
82 "supervisor interruption-handler definition removed": (
83 "def _install_interruption_handlers(supervisor: BoundGroup) -> None:"
85 "supervisor interruption-handler call removed":
"_install_interruption_handlers(supervisor)",
87SUPERVISOR_CASES_SEMANTIC_PROCESS_TOKENS = {
88 "emergency cleanup process identity check removed": (
89 " if not _identity_is_current(authority):\n return False"
91 "supervisor cases source-only sentinel removed": (
92 'globals().get("_RA8_SUPERVISOR_CASES_VERSION")'
94 "closed death descriptor source fd propagation removed": (
95 "inherited = [source_descriptor, root_descriptor]"
97 "closed death descriptor expected KILL status weakened": (
98 "return 0 if observed and cleaned and child.returncode == -signal.SIGKILL else 1"
100 "watchdog expiry pre-release proof removed": (
101 "pre_release_proven = killed_receipt and members is not None\n"
102 " pre_release_proven = pre_release_proven and members <= {authority.pid}"
104 "watchdog expiry test deadline extended": (
105 "launch = ControllerLaunch(entry, status, SELFTEST_WATCHDOG_TIMEOUT_SECONDS)"
107 "hardlink publication preservation proof removed": (
108 'preserved = victim.read_bytes() == b"preserve\\n" '
109 "and victim.stat().st_nlink == HARDLINK_COUNT"
111 "watchdog exact KILL receipt weakened": (
112 "killed = result.si_code == os.CLD_KILLED and result.si_status == signal.SIGKILL"
114 "watchdog runner liveness proof removed":
"if pre_release_proven and runner_is_live:",
115 "watchdog post-release group proof removed": (
116 "watchdog_succeeded = expected and _wait_group_gone(authority.group)"
118 "watchdog post-reap PID guard conflated with expected status": (
119 "runner_status = _wait_direct_child_status(runner)\n"
120 " runner_reaped = runner_status is not None\n"
121 " expected = runner_status == STALL_STATUS"
123 "hardlink runner post-reap signal guard removed": (
124 "if not hardlink_runner_reaped:\n with suppress(ProcessLookupError):"
126 "closed-controller command definition removed":
"def _closed_controller_command(",
127 "closed-controller command call removed": (
128 "command = _closed_controller_command(\n"
129 " entry_authority, status, death_descriptor, root_descriptor, "
132 " child = subprocess.Popen("
138 function: str, kind: str, entries: tuple[tuple[str, str], ...]
139) -> dict[str, tuple[str, str, str]]:
140 """Bind compact label/token data to one owning function."""
141 return {label: (function, kind, token)
for label, token
in entries}
144SUPERVISOR_CASES_SCOPED_PROCESS_TOKENS = {
146 "_closed_controller_command",
147 "command construction",
149 (
"closed-controller interpreter changed",
"sys.executable,"),
150 (
"closed-controller no-bytecode flag removed",
'"-B",'),
151 (
"closed-controller isolation flag removed",
'"-I",'),
152 (
"closed-controller site-import refusal removed",
'"-S",'),
153 (
"closed-controller supervisor authority removed",
"SUPERVISOR_PROGRAM,"),
154 (
"closed-controller mode removed",
'"--controller",'),
158 "_closed_controller_descriptor_selftest",
162 "closed-controller subreaper enable removed",
163 "if not supervisor.enable_subreaper():",
166 "closed-controller Popen descriptor propagation removed",
167 "pass_fds=tuple(inherited),",
170 "closed-controller Popen session isolation removed",
171 "start_new_session=True,",
174 "closed-controller bound adoption removed",
175 "supervisor.bind_spawned_child(child)",
180 "_watchdog_expiry_runner",
184 "watchdog identity receipt exact-write removed",
187 " identity_descriptor,\n"
188 ' f"{supervisor.pid}\\n".encode("ascii"),\n'
189 " RECEIPT_MAX_BYTES,\n"
194 "watchdog pre-proof containment removed",
195 "contained = supervisor.contain()",
198 "watchdog proof receipt exact-write removed",
201 " proof_descriptor,\n"
202 ' b"K\\n" if killed and contained else b"F\\n",\n'
203 " RECEIPT_MAX_BYTES,\n"
210 "_refused_controller_launch",
211 "command construction",
213 (
"refused-controller interpreter changed",
"sys.executable,"),
214 (
"refused-controller no-bytecode flag removed",
'"-B",'),
215 (
"refused-controller isolation flag removed",
'"-I",'),
216 (
"refused-controller site-import refusal removed",
'"-S",'),
217 (
"refused-controller supervisor authority removed",
"SUPERVISOR_PROGRAM,"),
218 (
"refused-controller mode removed",
'"--controller",'),
222 "_refused_controller_launch",
226 "refused-controller descriptor propagation removed",
227 "pass_fds=(source_descriptor, root_descriptor),",
229 (
"refused-controller session isolation removed",
"start_new_session=True,"),
234SUPERVISOR_SCOPED_LOADER_TOKENS = {
236 "_load_cases_dispatch",
239 (
"cases loader bound source read removed",
"source = _read_cases_source(descriptor)"),
240 (
"cases loader pre-exec digest binding removed",
"if digest != CASES_RAW_SHA256:"),
241 (
"cases loader namespace name binding removed",
'"__name__": "_ra8_supervisor_cases",'),
243 "cases loader namespace filename binding removed",
244 '"__file__": f"/proc/self/fd/{descriptor}",',
246 (
"cases loader grant version binding removed",
'"_RA8_SUPERVISOR_CASES_VERSION": 1,'),
248 "cases loader authenticated exec removed",
249 "exec( # noqa: S102 -- exact digest-bound source-only FD",
251 (
"cases loader compile source binding removed",
"compile(source,"),
253 "cases loader compile filename binding removed",
254 'namespace["__file__"],',
256 (
"cases loader compile exec-mode binding removed",
', "exec")'),
258 "cases loader grant exact consumption removed",
259 'grant = namespace.pop("_RA8_SUPERVISOR_CASES_VERSION", None)',
262 "cases loader grant absence postcondition removed",
263 'if grant != 1 or "_RA8_SUPERVISOR_CASES_VERSION" in namespace:',
266 "cases loader post-exec same-FD digest removed",
267 "if hashlib.sha256(_read_cases_source(descriptor)).hexdigest() != digest:",
269 (
"cases loader callable dispatch binding removed",
"if not callable(dispatch):"),
271 "cases loader dispatch namespace identity removed",
272 "if dispatch.__globals__ is not namespace:",
275 "cases loader descriptor final-close removed",
276 "finally:\n os.close(descriptor)",
281 "_read_cases_source",
284 (
"cases source metadata regular binding removed",
"stat.S_ISREG(metadata.st_mode)"),
285 (
"cases source metadata link binding removed",
"metadata.st_nlink == 1"),
286 (
"cases source metadata owner binding removed",
"metadata.st_uid == os.getuid()"),
287 (
"cases source metadata group binding removed",
"metadata.st_gid == os.getgid()"),
289 "cases source metadata mode binding removed",
290 "stat.S_IMODE(metadata.st_mode) == CASES_MODE",
292 (
"cases source metadata byte bound removed",
"0 < metadata.st_size <= CASES_MAX_BYTES"),
293 (
"cases source read step bound removed",
"for _step in range(CASES_READ_STEPS):"),
295 "cases source descriptor pread binding removed",
296 "chunk = os.pread(descriptor, 4096, offset)",
299 "cases source complete-size postcondition removed",
300 "if len(source) != metadata.st_size or len(source) > CASES_MAX_BYTES:",
306CROSS_LANGUAGE_SCOPED_TOKENS = (
308 "entry descriptor reservation call removed",
309 "devcontainer_image_selftest_process",
311 "descriptor = _reserve_entry_descriptor(descriptor)",
314 "entry descriptor propagation removed",
315 "devcontainer_image_selftest_process",
317 "inherited.append(self.entry_descriptor)",
320 "parent-death Popen descriptor propagation removed",
321 "devcontainer_image_selftest_process",
323 "pass_fds=tuple(inherited),",
326 "parent-death Popen session isolation removed",
327 "devcontainer_image_selftest_process",
329 "start_new_session=True,",
332 "entry descriptor high-FD duplication removed",
333 "devcontainer_image_selftest_process",
334 "_reserve_entry_descriptor",
337 " fcntl.F_DUPFD_CLOEXEC,\n"
338 " ENTRY_EXEC_DESCRIPTOR_MINIMUM,\n"
342 "entry descriptor original close removed",
343 "devcontainer_image_selftest_process",
344 "_reserve_entry_descriptor",
345 "os.close(descriptor)",
348 "entry descriptor CLOEXEC readback removed",
349 "devcontainer_image_selftest_process",
350 "_reserve_entry_descriptor",
351 "descriptor_flags = fcntl.fcntl(reserved, fcntl.F_GETFD)",
354 "entry descriptor reservation bound removed",
355 "devcontainer_image_selftest_process",
356 "_reserve_entry_descriptor",
357 "if reserved < ENTRY_EXEC_DESCRIPTOR_MINIMUM or not (",
360 "entry descriptor CLOEXEC predicate removed",
361 "devcontainer_image_selftest_process",
362 "_reserve_entry_descriptor",
363 "descriptor_flags & fcntl.FD_CLOEXEC",
366 "supervisor launcher bound entry environment removed",
367 "devcontainer_image_bound_exit_selftest",
368 "run_bound_exit_supervisor",
369 'RA8_SELFTEST_BOUND_ENTRY="$1"',
372 "supervisor launcher interpreter changed",
373 "devcontainer_image_bound_exit_selftest",
374 "run_bound_exit_supervisor",
378 "supervisor launcher no-bytecode flag removed",
379 "devcontainer_image_bound_exit_selftest",
380 "run_bound_exit_supervisor",
384 "supervisor launcher isolation flag removed",
385 "devcontainer_image_bound_exit_selftest",
386 "run_bound_exit_supervisor",
390 "supervisor launcher site-import refusal removed",
391 "devcontainer_image_bound_exit_selftest",
392 "run_bound_exit_supervisor",
396 "supervisor launcher bound program removed",
397 "devcontainer_image_bound_exit_selftest",
398 "run_bound_exit_supervisor",
402 "supervisor launcher process descriptor option removed",
403 "devcontainer_image_bound_exit_selftest",
404 "run_bound_exit_supervisor",
408 "supervisor launcher process descriptor changed",
409 "devcontainer_image_bound_exit_selftest",
410 "run_bound_exit_supervisor",
414 "supervisor launcher cases descriptor option removed",
415 "devcontainer_image_bound_exit_selftest",
416 "run_bound_exit_supervisor",
420 "supervisor launcher cases descriptor changed",
421 "devcontainer_image_bound_exit_selftest",
422 "run_bound_exit_supervisor",
426 "payload entry descriptor metadata binding removed",
427 "devcontainer_image_selftest_supervisor",
429 "if not _entry_metadata_is_safe(metadata):",
432 "payload procfd path binding removed",
433 "devcontainer_image_selftest_supervisor",
435 'entry = f"/proc/self/fd/{descriptor}"',
438 "payload post-exec pathname identity removed",
439 "devcontainer_image_selftest_process",
440 "BoundGroup._close_entry_authority",
441 "and (path_metadata.st_dev, path_metadata.st_ino) == self.entry_identity",
444 "payload post-exec descriptor identity removed",
445 "devcontainer_image_selftest_process",
446 "BoundGroup._close_entry_authority",
447 "and current_identity == self.entry_identity",
450 "payload post-exec digest proof removed",
451 "devcontainer_image_selftest_process",
452 "BoundGroup._close_entry_authority",
453 "and current_digest == self.entry_digest",
456 "main suite-root canonical tmp changed",
457 "devcontainer_image_selftest_supervisor",
459 '"/tmp" # noqa: S108 -- fixed physical parent; random mode-0700 inode-bound direct child',
462 "main suite-root canonical parent removed",
463 "devcontainer_image_selftest_supervisor",
464 "_suite_root_path_is_safe",
465 "and root.parent == canonical",
468 "main suite-root direct resolution removed",
469 "devcontainer_image_selftest_supervisor",
470 "_suite_root_path_is_safe",
471 "and resolved == root",
474 "main suite-root suffix length removed",
475 "devcontainer_image_selftest_supervisor",
476 "_suite_root_path_is_safe",
477 "and len(suffix) == SUITE_ROOT_SUFFIX_LENGTH",
480 "main suite-root hex suffix removed",
481 "devcontainer_image_selftest_supervisor",
482 "_suite_root_path_is_safe",
483 'and all(character in "0123456789abcdef" for character in suffix)',
486 "main suite-root directory type removed",
487 "devcontainer_image_selftest_supervisor",
488 "_suite_root_metadata_is_safe",
489 "stat.S_ISDIR(metadata.st_mode)",
492 "main suite-root owner removed",
493 "devcontainer_image_selftest_supervisor",
494 "_suite_root_metadata_is_safe",
495 "and metadata.st_uid == os.getuid()",
498 "main suite-root group removed",
499 "devcontainer_image_selftest_supervisor",
500 "_suite_root_metadata_is_safe",
501 "and metadata.st_gid == os.getgid()",
504 "main suite-root private mode removed",
505 "devcontainer_image_selftest_supervisor",
506 "_suite_root_metadata_is_safe",
507 "and stat.S_IMODE(metadata.st_mode) == PRIVATE_MODE",
510 "main suite-root inode identity removed",
511 "devcontainer_image_selftest_supervisor",
512 "_open_suite_root_authority",
513 "if not _suite_root_metadata_is_safe(after) or identity != (\n"
514 " before.st_dev,\n before.st_ino,\n ):",
517 "cases suite-root canonical tmp changed",
518 "devcontainer_image_selftest_supervisor_cases",
520 '"/tmp" # noqa: S108 -- fixed physical parent; random mode-0700 inode-bound direct child',
523 "cases suite-root canonical parent removed",
524 "devcontainer_image_selftest_supervisor_cases",
525 "_suite_root_is_safe",
526 "and root.parent == canonical",
529 "cases suite-root direct resolution removed",
530 "devcontainer_image_selftest_supervisor_cases",
531 "_suite_root_is_safe",
532 "and resolved == root",
535 "cases suite-root suffix length removed",
536 "devcontainer_image_selftest_supervisor_cases",
537 "_suite_root_is_safe",
538 "and len(suffix) == SUITE_ROOT_SUFFIX_LENGTH",
541 "cases suite-root hex suffix removed",
542 "devcontainer_image_selftest_supervisor_cases",
543 "_suite_root_is_safe",
544 'and all(character in "0123456789abcdef" for character in suffix)',
547 "cases suite-root directory type removed",
548 "devcontainer_image_selftest_supervisor_cases",
549 "_suite_root_is_safe",
550 "and stat.S_ISDIR(metadata.st_mode)",
553 "cases suite-root owner removed",
554 "devcontainer_image_selftest_supervisor_cases",
555 "_suite_root_is_safe",
556 "and metadata.st_uid == os.getuid()",
559 "cases suite-root group removed",
560 "devcontainer_image_selftest_supervisor_cases",
561 "_suite_root_is_safe",
562 "and metadata.st_gid == os.getgid()",
565 "cases suite-root private mode removed",
566 "devcontainer_image_selftest_supervisor_cases",
567 "_suite_root_is_safe",
568 "and stat.S_IMODE(metadata.st_mode) == PRIVATE_MODE",
571 "cases suite-root inode identity removed",
572 "devcontainer_image_selftest_supervisor_cases",
573 "_suite_root_is_safe",
574 "and identity == expected_identity",
577 "spawn handler name grammar removed",
578 "devcontainer_image_selftest",
579 "begin_selftest_spawn_critical",
580 '[[ "$handler" =~ ^[a-z_][a-z0-9_]*$ ]]',
583 "spawn handler function binding removed",
584 "devcontainer_image_selftest",
585 "begin_selftest_spawn_critical",
586 'declare -F "$handler" >/dev/null',
589 "spawn EXIT handler binding removed",
590 "devcontainer_image_selftest",
591 "finish_selftest_spawn_critical",
592 'trap "$handler \\$?" EXIT',
595 "spawn HUP handler binding removed",
596 "devcontainer_image_selftest",
597 "finish_selftest_spawn_critical",
598 'trap "$handler 129" HUP',
601 "spawn INT handler binding removed",
602 "devcontainer_image_selftest",
603 "finish_selftest_spawn_critical",
604 'trap "$handler 130" INT',
607 "spawn TERM handler binding removed",
608 "devcontainer_image_selftest",
609 "finish_selftest_spawn_critical",
610 'trap "$handler 143" TERM',
613 "allocation launcher execv removed",
614 "devcontainer_image_selftest_cases",
615 "selftest_allocation_signal_path",
619 "allocation launcher Bash executable changed",
620 "devcontainer_image_selftest_cases",
621 "selftest_allocation_signal_path",
625 "allocation launcher Bash argv0 changed",
626 "devcontainer_image_selftest_cases",
627 "selftest_allocation_signal_path",
631 "allocation launcher protected Bash flag removed",
632 "devcontainer_image_selftest_cases",
633 "selftest_allocation_signal_path",
637 "allocation launcher option terminator removed",
638 "devcontainer_image_selftest_cases",
639 "selftest_allocation_signal_path",
643 "allocation launcher Python interpreter changed",
644 "devcontainer_image_selftest_cases",
645 "selftest_allocation_signal_path",
649 "allocation launcher no-bytecode flag removed",
650 "devcontainer_image_selftest_cases",
651 "selftest_allocation_signal_path",
655 "allocation launcher isolation flag removed",
656 "devcontainer_image_selftest_cases",
657 "selftest_allocation_signal_path",
661 "allocation launcher site-import refusal removed",
662 "devcontainer_image_selftest_cases",
663 "selftest_allocation_signal_path",
667 "allocation launcher command-string mode removed",
668 "devcontainer_image_selftest_cases",
669 "selftest_allocation_signal_path",
673 "signal launcher execv removed",
674 "devcontainer_image_signal_selftest",
675 "start_signal_controller",
679 "signal launcher Bash executable changed",
680 "devcontainer_image_signal_selftest",
681 "start_signal_controller",
685 "signal launcher Bash argv0 changed",
686 "devcontainer_image_signal_selftest",
687 "start_signal_controller",
691 "signal launcher protected Bash flag removed",
692 "devcontainer_image_signal_selftest",
693 "start_signal_controller",
697 "signal launcher option terminator removed",
698 "devcontainer_image_signal_selftest",
699 "start_signal_controller",
703 "signal launcher session isolation removed",
704 "devcontainer_image_signal_selftest",
705 "start_signal_controller",
709 "signal launcher Python interpreter changed",
710 "devcontainer_image_signal_selftest",
711 "start_signal_controller",
715 "signal launcher no-bytecode flag removed",
716 "devcontainer_image_signal_selftest",
717 "start_signal_controller",
721 "signal launcher isolation flag removed",
722 "devcontainer_image_signal_selftest",
723 "start_signal_controller",
727 "signal launcher site-import refusal removed",
728 "devcontainer_image_signal_selftest",
729 "start_signal_controller",
733 "signal launcher command-string mode removed",
734 "devcontainer_image_signal_selftest",
735 "start_signal_controller",
740TRIPWIRE_LABELS = (
"replaced-lock build tripwire removed",
"missing-lock build tripwire removed")
741TRIPWIRE_PATTERN =
'build_image() { : >"$marker"; }'