ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
hil_convergence_safety_image_process_policy.py
Go to the documentation of this file.
1# SPDX-License-Identifier: MIT
2# Copyright (c) 2026 Brighton Sikarskie
3"""Scoped process-authority policy for devcontainer image selftests."""
4
5from __future__ import annotations
6
7PROCESS_MODULE_SEMANTIC_TOKENS = {
8 "entry descriptor floor lowered into helper range": "ENTRY_EXEC_DESCRIPTOR_MINIMUM = 64",
9}
10
11SUPERVISOR_SEMANTIC_PROCESS_TOKENS = {
12 "bound-exit supervisor pre-spawn signal block removed": (
13 "old_mask = signal.pthread_sigmask(signal.SIG_BLOCK, MANAGED_SIGNALS)"
14 ),
15 "bound-exit parent-death pipe removed": (
16 "self.death_read, self.death_write = os.pipe2(os.O_CLOEXEC)"
17 ),
18 "bound-exit parent-death descriptor propagation removed": (
19 "inherited = [source_descriptor, self.death_read, root_descriptor]"
20 ),
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",'
27 ),
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)"
32 ),
33 "bound-exit payload signal reset removed": (
34 " _reset_managed_signals()\n"
35 " try:\n"
36 " os.execl( # noqa: S606 -- fixed Bash and descriptor-bound entry"
37 ),
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)"
43 ),
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)"
49 ),
50 "bound-exit terminal payload is polled after reap": (
51 " if not published:\n child_status = _poll_payload(child)"
52 ),
53 "bound-exit controller liveness proof removed": (
54 ' supervisor.require_running("after publishing status")'
55 ),
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"
60 ),
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)"
65 ),
66 "bound receipt exact-write use removed": (
67 " _write_exact(descriptor, payload, RECEIPT_MAX_BYTES)"
68 ),
69 "status receipt no-follow descriptor removed": (
70 " descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)"
71 ),
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:"
77 ),
78 "bound-exit status atomic publication removed": (
79 "os.link(temporary, path, follow_symlinks=False)"
80 ),
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:"
84 ),
85 "supervisor interruption-handler call removed": "_install_interruption_handlers(supervisor)",
86}
87SUPERVISOR_CASES_SEMANTIC_PROCESS_TOKENS = {
88 "emergency cleanup process identity check removed": (
89 " if not _identity_is_current(authority):\n return False"
90 ),
91 "supervisor cases source-only sentinel removed": (
92 'globals().get("_RA8_SUPERVISOR_CASES_VERSION")'
93 ),
94 "closed death descriptor source fd propagation removed": (
95 "inherited = [source_descriptor, root_descriptor]"
96 ),
97 "closed death descriptor expected KILL status weakened": (
98 "return 0 if observed and cleaned and child.returncode == -signal.SIGKILL else 1"
99 ),
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}"
103 ),
104 "watchdog expiry test deadline extended": (
105 "launch = ControllerLaunch(entry, status, SELFTEST_WATCHDOG_TIMEOUT_SECONDS)"
106 ),
107 "hardlink publication preservation proof removed": (
108 'preserved = victim.read_bytes() == b"preserve\\n" '
109 "and victim.stat().st_nlink == HARDLINK_COUNT"
110 ),
111 "watchdog exact KILL receipt weakened": (
112 "killed = result.si_code == os.CLD_KILLED and result.si_status == signal.SIGKILL"
113 ),
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)"
117 ),
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"
122 ),
123 "hardlink runner post-reap signal guard removed": (
124 "if not hardlink_runner_reaped:\n with suppress(ProcessLookupError):"
125 ),
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, "
130 "root_identity\n"
131 " )\n"
132 " child = subprocess.Popen("
133 ),
134}
135
136
137def _scoped_specs(
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}
142
143
144SUPERVISOR_CASES_SCOPED_PROCESS_TOKENS = {
145 **_scoped_specs(
146 "_closed_controller_command",
147 "command construction",
148 (
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",'),
155 ),
156 ),
157 **_scoped_specs(
158 "_closed_controller_descriptor_selftest",
159 "Popen authority",
160 (
161 (
162 "closed-controller subreaper enable removed",
163 "if not supervisor.enable_subreaper():",
164 ),
165 (
166 "closed-controller Popen descriptor propagation removed",
167 "pass_fds=tuple(inherited),",
168 ),
169 (
170 "closed-controller Popen session isolation removed",
171 "start_new_session=True,",
172 ),
173 (
174 "closed-controller bound adoption removed",
175 "supervisor.bind_spawned_child(child)",
176 ),
177 ),
178 ),
179 **_scoped_specs(
180 "_watchdog_expiry_runner",
181 "containment proof",
182 (
183 (
184 "watchdog identity receipt exact-write removed",
185 (
186 " _write_exact(\n"
187 " identity_descriptor,\n"
188 ' f"{supervisor.pid}\\n".encode("ascii"),\n'
189 " RECEIPT_MAX_BYTES,\n"
190 " )"
191 ),
192 ),
193 (
194 "watchdog pre-proof containment removed",
195 "contained = supervisor.contain()",
196 ),
197 (
198 "watchdog proof receipt exact-write removed",
199 (
200 " _write_exact(\n"
201 " proof_descriptor,\n"
202 ' b"K\\n" if killed and contained else b"F\\n",\n'
203 " RECEIPT_MAX_BYTES,\n"
204 " )"
205 ),
206 ),
207 ),
208 ),
209 **_scoped_specs(
210 "_refused_controller_launch",
211 "command construction",
212 (
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",'),
219 ),
220 ),
221 **_scoped_specs(
222 "_refused_controller_launch",
223 "Popen authority",
224 (
225 (
226 "refused-controller descriptor propagation removed",
227 "pass_fds=(source_descriptor, root_descriptor),",
228 ),
229 ("refused-controller session isolation removed", "start_new_session=True,"),
230 ),
231 ),
232}
233
234SUPERVISOR_SCOPED_LOADER_TOKENS = {
235 **_scoped_specs(
236 "_load_cases_dispatch",
237 "loader binding",
238 (
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",'),
242 (
243 "cases loader namespace filename binding removed",
244 '"__file__": f"/proc/self/fd/{descriptor}",',
245 ),
246 ("cases loader grant version binding removed", '"_RA8_SUPERVISOR_CASES_VERSION": 1,'),
247 (
248 "cases loader authenticated exec removed",
249 "exec( # noqa: S102 -- exact digest-bound source-only FD",
250 ),
251 ("cases loader compile source binding removed", "compile(source,"),
252 (
253 "cases loader compile filename binding removed",
254 'namespace["__file__"],',
255 ),
256 ("cases loader compile exec-mode binding removed", ', "exec")'),
257 (
258 "cases loader grant exact consumption removed",
259 'grant = namespace.pop("_RA8_SUPERVISOR_CASES_VERSION", None)',
260 ),
261 (
262 "cases loader grant absence postcondition removed",
263 'if grant != 1 or "_RA8_SUPERVISOR_CASES_VERSION" in namespace:',
264 ),
265 (
266 "cases loader post-exec same-FD digest removed",
267 "if hashlib.sha256(_read_cases_source(descriptor)).hexdigest() != digest:",
268 ),
269 ("cases loader callable dispatch binding removed", "if not callable(dispatch):"),
270 (
271 "cases loader dispatch namespace identity removed",
272 "if dispatch.__globals__ is not namespace:",
273 ),
274 (
275 "cases loader descriptor final-close removed",
276 "finally:\n os.close(descriptor)",
277 ),
278 ),
279 ),
280 **_scoped_specs(
281 "_read_cases_source",
282 "source binding",
283 (
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()"),
288 (
289 "cases source metadata mode binding removed",
290 "stat.S_IMODE(metadata.st_mode) == CASES_MODE",
291 ),
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):"),
294 (
295 "cases source descriptor pread binding removed",
296 "chunk = os.pread(descriptor, 4096, offset)",
297 ),
298 (
299 "cases source complete-size postcondition removed",
300 "if len(source) != metadata.st_size or len(source) > CASES_MAX_BYTES:",
301 ),
302 ),
303 ),
304}
305
306CROSS_LANGUAGE_SCOPED_TOKENS = (
307 (
308 "entry descriptor reservation call removed",
309 "devcontainer_image_selftest_process",
310 "BoundGroup.spawn",
311 "descriptor = _reserve_entry_descriptor(descriptor)",
312 ),
313 (
314 "entry descriptor propagation removed",
315 "devcontainer_image_selftest_process",
316 "BoundGroup.spawn",
317 "inherited.append(self.entry_descriptor)",
318 ),
319 (
320 "parent-death Popen descriptor propagation removed",
321 "devcontainer_image_selftest_process",
322 "BoundGroup.spawn",
323 "pass_fds=tuple(inherited),",
324 ),
325 (
326 "parent-death Popen session isolation removed",
327 "devcontainer_image_selftest_process",
328 "BoundGroup.spawn",
329 "start_new_session=True,",
330 ),
331 (
332 "entry descriptor high-FD duplication removed",
333 "devcontainer_image_selftest_process",
334 "_reserve_entry_descriptor",
335 "fcntl.fcntl(\n"
336 " descriptor,\n"
337 " fcntl.F_DUPFD_CLOEXEC,\n"
338 " ENTRY_EXEC_DESCRIPTOR_MINIMUM,\n"
339 " )",
340 ),
341 (
342 "entry descriptor original close removed",
343 "devcontainer_image_selftest_process",
344 "_reserve_entry_descriptor",
345 "os.close(descriptor)",
346 ),
347 (
348 "entry descriptor CLOEXEC readback removed",
349 "devcontainer_image_selftest_process",
350 "_reserve_entry_descriptor",
351 "descriptor_flags = fcntl.fcntl(reserved, fcntl.F_GETFD)",
352 ),
353 (
354 "entry descriptor reservation bound removed",
355 "devcontainer_image_selftest_process",
356 "_reserve_entry_descriptor",
357 "if reserved < ENTRY_EXEC_DESCRIPTOR_MINIMUM or not (",
358 ),
359 (
360 "entry descriptor CLOEXEC predicate removed",
361 "devcontainer_image_selftest_process",
362 "_reserve_entry_descriptor",
363 "descriptor_flags & fcntl.FD_CLOEXEC",
364 ),
365 (
366 "supervisor launcher bound entry environment removed",
367 "devcontainer_image_bound_exit_selftest",
368 "run_bound_exit_supervisor",
369 'RA8_SELFTEST_BOUND_ENTRY="$1"',
370 ),
371 (
372 "supervisor launcher interpreter changed",
373 "devcontainer_image_bound_exit_selftest",
374 "run_bound_exit_supervisor",
375 "/usr/bin/python3",
376 ),
377 (
378 "supervisor launcher no-bytecode flag removed",
379 "devcontainer_image_bound_exit_selftest",
380 "run_bound_exit_supervisor",
381 " -B ",
382 ),
383 (
384 "supervisor launcher isolation flag removed",
385 "devcontainer_image_bound_exit_selftest",
386 "run_bound_exit_supervisor",
387 " -I ",
388 ),
389 (
390 "supervisor launcher site-import refusal removed",
391 "devcontainer_image_bound_exit_selftest",
392 "run_bound_exit_supervisor",
393 " -S ",
394 ),
395 (
396 "supervisor launcher bound program removed",
397 "devcontainer_image_bound_exit_selftest",
398 "run_bound_exit_supervisor",
399 '"$program"',
400 ),
401 (
402 "supervisor launcher process descriptor option removed",
403 "devcontainer_image_bound_exit_selftest",
404 "run_bound_exit_supervisor",
405 " --process-fd ",
406 ),
407 (
408 "supervisor launcher process descriptor changed",
409 "devcontainer_image_bound_exit_selftest",
410 "run_bound_exit_supervisor",
411 " 9 ",
412 ),
413 (
414 "supervisor launcher cases descriptor option removed",
415 "devcontainer_image_bound_exit_selftest",
416 "run_bound_exit_supervisor",
417 " --cases-fd ",
418 ),
419 (
420 "supervisor launcher cases descriptor changed",
421 "devcontainer_image_bound_exit_selftest",
422 "run_bound_exit_supervisor",
423 " 8 ",
424 ),
425 (
426 "payload entry descriptor metadata binding removed",
427 "devcontainer_image_selftest_supervisor",
428 "_spawn_payload",
429 "if not _entry_metadata_is_safe(metadata):",
430 ),
431 (
432 "payload procfd path binding removed",
433 "devcontainer_image_selftest_supervisor",
434 "_spawn_payload",
435 'entry = f"/proc/self/fd/{descriptor}"',
436 ),
437 (
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",
442 ),
443 (
444 "payload post-exec descriptor identity removed",
445 "devcontainer_image_selftest_process",
446 "BoundGroup._close_entry_authority",
447 "and current_identity == self.entry_identity",
448 ),
449 (
450 "payload post-exec digest proof removed",
451 "devcontainer_image_selftest_process",
452 "BoundGroup._close_entry_authority",
453 "and current_digest == self.entry_digest",
454 ),
455 (
456 "main suite-root canonical tmp changed",
457 "devcontainer_image_selftest_supervisor",
458 "<module>",
459 '"/tmp" # noqa: S108 -- fixed physical parent; random mode-0700 inode-bound direct child',
460 ),
461 (
462 "main suite-root canonical parent removed",
463 "devcontainer_image_selftest_supervisor",
464 "_suite_root_path_is_safe",
465 "and root.parent == canonical",
466 ),
467 (
468 "main suite-root direct resolution removed",
469 "devcontainer_image_selftest_supervisor",
470 "_suite_root_path_is_safe",
471 "and resolved == root",
472 ),
473 (
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",
478 ),
479 (
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)',
484 ),
485 (
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)",
490 ),
491 (
492 "main suite-root owner removed",
493 "devcontainer_image_selftest_supervisor",
494 "_suite_root_metadata_is_safe",
495 "and metadata.st_uid == os.getuid()",
496 ),
497 (
498 "main suite-root group removed",
499 "devcontainer_image_selftest_supervisor",
500 "_suite_root_metadata_is_safe",
501 "and metadata.st_gid == os.getgid()",
502 ),
503 (
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",
508 ),
509 (
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 ):",
515 ),
516 (
517 "cases suite-root canonical tmp changed",
518 "devcontainer_image_selftest_supervisor_cases",
519 "<module>",
520 '"/tmp" # noqa: S108 -- fixed physical parent; random mode-0700 inode-bound direct child',
521 ),
522 (
523 "cases suite-root canonical parent removed",
524 "devcontainer_image_selftest_supervisor_cases",
525 "_suite_root_is_safe",
526 "and root.parent == canonical",
527 ),
528 (
529 "cases suite-root direct resolution removed",
530 "devcontainer_image_selftest_supervisor_cases",
531 "_suite_root_is_safe",
532 "and resolved == root",
533 ),
534 (
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",
539 ),
540 (
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)',
545 ),
546 (
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)",
551 ),
552 (
553 "cases suite-root owner removed",
554 "devcontainer_image_selftest_supervisor_cases",
555 "_suite_root_is_safe",
556 "and metadata.st_uid == os.getuid()",
557 ),
558 (
559 "cases suite-root group removed",
560 "devcontainer_image_selftest_supervisor_cases",
561 "_suite_root_is_safe",
562 "and metadata.st_gid == os.getgid()",
563 ),
564 (
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",
569 ),
570 (
571 "cases suite-root inode identity removed",
572 "devcontainer_image_selftest_supervisor_cases",
573 "_suite_root_is_safe",
574 "and identity == expected_identity",
575 ),
576 (
577 "spawn handler name grammar removed",
578 "devcontainer_image_selftest",
579 "begin_selftest_spawn_critical",
580 '[[ "$handler" =~ ^[a-z_][a-z0-9_]*$ ]]',
581 ),
582 (
583 "spawn handler function binding removed",
584 "devcontainer_image_selftest",
585 "begin_selftest_spawn_critical",
586 'declare -F "$handler" >/dev/null',
587 ),
588 (
589 "spawn EXIT handler binding removed",
590 "devcontainer_image_selftest",
591 "finish_selftest_spawn_critical",
592 'trap "$handler \\$?" EXIT',
593 ),
594 (
595 "spawn HUP handler binding removed",
596 "devcontainer_image_selftest",
597 "finish_selftest_spawn_critical",
598 'trap "$handler 129" HUP',
599 ),
600 (
601 "spawn INT handler binding removed",
602 "devcontainer_image_selftest",
603 "finish_selftest_spawn_critical",
604 'trap "$handler 130" INT',
605 ),
606 (
607 "spawn TERM handler binding removed",
608 "devcontainer_image_selftest",
609 "finish_selftest_spawn_critical",
610 'trap "$handler 143" TERM',
611 ),
612 (
613 "allocation launcher execv removed",
614 "devcontainer_image_selftest_cases",
615 "selftest_allocation_signal_path",
616 "os.execv(",
617 ),
618 (
619 "allocation launcher Bash executable changed",
620 "devcontainer_image_selftest_cases",
621 "selftest_allocation_signal_path",
622 '"/bin/bash", [',
623 ),
624 (
625 "allocation launcher Bash argv0 changed",
626 "devcontainer_image_selftest_cases",
627 "selftest_allocation_signal_path",
628 '["/bin/bash",',
629 ),
630 (
631 "allocation launcher protected Bash flag removed",
632 "devcontainer_image_selftest_cases",
633 "selftest_allocation_signal_path",
634 '"-p",',
635 ),
636 (
637 "allocation launcher option terminator removed",
638 "devcontainer_image_selftest_cases",
639 "selftest_allocation_signal_path",
640 '"--",',
641 ),
642 (
643 "allocation launcher Python interpreter changed",
644 "devcontainer_image_selftest_cases",
645 "selftest_allocation_signal_path",
646 "/usr/bin/python3",
647 ),
648 (
649 "allocation launcher no-bytecode flag removed",
650 "devcontainer_image_selftest_cases",
651 "selftest_allocation_signal_path",
652 " -B ",
653 ),
654 (
655 "allocation launcher isolation flag removed",
656 "devcontainer_image_selftest_cases",
657 "selftest_allocation_signal_path",
658 " -I ",
659 ),
660 (
661 "allocation launcher site-import refusal removed",
662 "devcontainer_image_selftest_cases",
663 "selftest_allocation_signal_path",
664 " -S ",
665 ),
666 (
667 "allocation launcher command-string mode removed",
668 "devcontainer_image_selftest_cases",
669 "selftest_allocation_signal_path",
670 " -c ",
671 ),
672 (
673 "signal launcher execv removed",
674 "devcontainer_image_signal_selftest",
675 "start_signal_controller",
676 "os.execv(",
677 ),
678 (
679 "signal launcher Bash executable changed",
680 "devcontainer_image_signal_selftest",
681 "start_signal_controller",
682 '"/bin/bash", [',
683 ),
684 (
685 "signal launcher Bash argv0 changed",
686 "devcontainer_image_signal_selftest",
687 "start_signal_controller",
688 '["/bin/bash",',
689 ),
690 (
691 "signal launcher protected Bash flag removed",
692 "devcontainer_image_signal_selftest",
693 "start_signal_controller",
694 '"-p",',
695 ),
696 (
697 "signal launcher option terminator removed",
698 "devcontainer_image_signal_selftest",
699 "start_signal_controller",
700 '"--",',
701 ),
702 (
703 "signal launcher session isolation removed",
704 "devcontainer_image_signal_selftest",
705 "start_signal_controller",
706 "/usr/bin/setsid ",
707 ),
708 (
709 "signal launcher Python interpreter changed",
710 "devcontainer_image_signal_selftest",
711 "start_signal_controller",
712 "/usr/bin/python3",
713 ),
714 (
715 "signal launcher no-bytecode flag removed",
716 "devcontainer_image_signal_selftest",
717 "start_signal_controller",
718 " -B ",
719 ),
720 (
721 "signal launcher isolation flag removed",
722 "devcontainer_image_signal_selftest",
723 "start_signal_controller",
724 " -I ",
725 ),
726 (
727 "signal launcher site-import refusal removed",
728 "devcontainer_image_signal_selftest",
729 "start_signal_controller",
730 " -S ",
731 ),
732 (
733 "signal launcher command-string mode removed",
734 "devcontainer_image_signal_selftest",
735 "start_signal_controller",
736 " -c ",
737 ),
738)
739
740TRIPWIRE_LABELS = ("replaced-lock build tripwire removed", "missing-lock build tripwire removed")
741TRIPWIRE_PATTERN = 'build_image() { : >"$marker"; }'