ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
hil_convergence_safety_process_source_fixtures.py
Go to the documentation of this file.
1# SPDX-License-Identifier: MIT
2# Copyright (c) 2026 Brighton Sikarskie
3"""Exact source mutations for the authenticated supervisor process boundary."""
4
5from __future__ import annotations
6
7from hil_convergence_safety_image_subreaper_policy import PROCESS_LOADER_TOKENS
8
9Mutation = tuple[str, str, str, str]
10PROCESS = "devcontainer_image_selftest_process"
11SUPERVISOR = "devcontainer_image_selftest_supervisor"
12SUPERVISOR_CASES = "devcontainer_image_selftest_supervisor_cases"
13_selftest_key = "devcontainer_image_selftest"
14_selftest_cases_key = "devcontainer_image_selftest_cases"
15_signal_selftest_key = "devcontainer_image_signal_selftest"
16
17
18def _process_mutations_1() -> tuple[Mutation, ...]:
19 """Return exact subreaper capability and child-binding mutations."""
20 return (
21 (
22 "child subreaper capability constant changed",
23 PROCESS,
24 "PR_SET_CHILD_SUBREAPER = 36",
25 "PR_SET_CHILD_SUBREAPER = 0",
26 ),
27 (
28 "child subreaper verification constant changed",
29 PROCESS,
30 "PR_GET_CHILD_SUBREAPER = 37",
31 "PR_GET_CHILD_SUBREAPER = 0",
32 ),
33 (
34 "child subreaper prctl activation removed",
35 PROCESS,
36 "if prctl(PR_SET_CHILD_SUBREAPER, 1, 0, 0, 0) != 0:",
37 "if False:",
38 ),
39 (
40 "child subreaper prctl verification removed",
41 PROCESS,
42 "result = prctl(PR_GET_CHILD_SUBREAPER, ctypes.addressof(state), 0, 0, 0)",
43 "result = 0",
44 ),
45 (
46 "child subreaper verified-state proof removed",
47 PROCESS,
48 "return result == 0 and state.value == 1",
49 "return result == 0",
50 ),
51 (
52 "child subreaper activation assignment removed",
53 PROCESS,
54 " self.subreaper = _enable_child_subreaper()",
55 " self.subreaper = True",
56 ),
57 (
58 "child subreaper initial-empty proof removed",
59 PROCESS,
60 "return self.subreaper and _child_table_is_empty()",
61 "return self.subreaper",
62 ),
63 (
64 "child subreaper direct-parent binding removed",
65 PROCESS,
66 " if parent != os.getpid() or identity is None:\n return None",
67 " if identity is None:\n return None",
68 ),
69 )
70
71
72def _manual_child_mutations() -> tuple[Mutation, ...]:
73 """Return exact manual-child binding mutations."""
74 return (
75 (
76 "manual child subreaper gate removed",
77 PROCESS,
78 " if not self.subreaper or self.child is not None or self.pid is not None:",
79 " if False:",
80 ),
81 (
82 "manual child containment binding removed",
83 PROCESS,
84 " self.child = child\n"
85 " self.pid = child.pid\n"
86 " self.children_contained = False",
87 " self.child = child\n"
88 " self.pid = child.pid\n"
89 " self.children_contained = True",
90 ),
91 (
92 "manual child isolated identity proof removed",
93 PROCESS,
94 " and identity.pid == identity.group == identity.session",
95 " and identity.pid > 0",
96 ),
97 (
98 "manual child direct-parent identity proof removed",
99 PROCESS,
100 " and children.get(child.pid) == identity",
101 " and children is not None",
102 ),
103 )
104
105
106def _manual_terminal_mutations() -> tuple[Mutation, ...]:
107 """Return exact unreaped terminal-child authority mutations."""
108 return (
109 (
110 "manual child terminal authority initialization removed",
111 PROCESS,
112 " self.leader_terminal = False",
113 " self.leader_terminal = True",
114 ),
115 (
116 "manual child WNOWAIT observation removed",
117 PROCESS,
118 " terminal = os.waitid(\n"
119 " os.P_PID,\n"
120 " child.pid,\n"
121 " os.WEXITED | os.WNOHANG | os.WNOWAIT,\n"
122 " )",
123 " terminal = None",
124 ),
125 (
126 "manual child early-reap PID release removed",
127 PROCESS,
128 " except ChildProcessError:\n"
129 " self.reaped = True\n"
130 " self.leader_terminal = True",
131 " except ChildProcessError:\n self.leader_terminal = True",
132 ),
133 (
134 "manual child terminal state binding removed",
135 PROCESS,
136 " self.leader_terminal = terminal is not None",
137 " self.leader_terminal = bool(terminal)",
138 ),
139 (
140 "manual terminal child signal bypass removed",
141 PROCESS,
142 " if self.leader_terminal:\n return self._finish_terminal_leader()",
143 " if False:\n return self._finish_terminal_leader()",
144 ),
145 )
146
147
148def _adopted_drain_mutations() -> tuple[Mutation, ...]:
149 """Return exact retained-leader and pre-reap descendant-drain mutations."""
150 return (
151 (
152 "child subreaper leader exclusion removed",
153 PROCESS,
154 " leader = children.pop(excluded_pid, None)\n"
155 " if leader != self.leader_identity:",
156 " leader = self.leader_identity\n"
157 " if leader != self.leader_identity:",
158 ),
159 (
160 "child subreaper adopted exclusion dispatch removed",
161 PROCESS,
162 " children = self._bound_direct_children(excluded_pid)",
163 " children = _direct_children()",
164 ),
165 (
166 "child subreaper leader WNOWAIT retention removed",
167 PROCESS,
168 " result = os.waitid(\n"
169 " os.P_PID,\n"
170 " self.pid,\n"
171 " os.WEXITED | os.WNOHANG | os.WNOWAIT,\n"
172 " )",
173 " result = os.waitid(\n"
174 " os.P_PID, self.pid, os.WEXITED | os.WNOHANG\n"
175 " )",
176 ),
177 (
178 "child subreaper lost authority fail-stop removed",
179 PROCESS,
180 " if self.authority_lost:\n return False",
181 " if False:\n return False",
182 ),
183 (
184 "child subreaper pre-reap adopted drain removed",
185 PROCESS,
186 " descendants_drained = leader_terminal and "
187 "self._cleanup_adopted_children(leader)",
188 " descendants_drained = leader_terminal",
189 ),
190 )
191
192
193def _process_mutations_2() -> tuple[Mutation, ...]:
194 """Return exact subreaper signal, reap, and containment mutations."""
195 return (
196 (
197 "child subreaper exact kill removed",
198 PROCESS,
199 "os.kill(authority.pid, signal.SIGKILL)",
200 "os.kill(authority.pid, signal.SIGTERM)",
201 ),
202 (
203 "child subreaper pre-signal identity proof removed",
204 PROCESS,
205 " if _bind_process(authority.pid) != authority:\n"
206 " return False\n"
207 " with suppress(ProcessLookupError):",
208 " if False:\n"
209 " return False\n"
210 " with suppress(ProcessLookupError):",
211 ),
212 (
213 "child subreaper WNOWAIT proof removed",
214 PROCESS,
215 " result = os.waitid(\n"
216 " os.P_PID,\n"
217 " authority.pid,\n"
218 " os.WEXITED | os.WNOHANG | os.WNOWAIT,\n"
219 " )",
220 " result = os.waitid(\n"
221 " os.P_PID, authority.pid, os.WEXITED | os.WNOHANG\n )",
222 ),
223 (
224 "child subreaper pre-reap identity proof removed",
225 PROCESS,
226 " if _bind_process(authority.pid) != authority:\n"
227 " return False\n"
228 " waited, _status = os.waitpid(authority.pid, 0)",
229 " if False:\n return False\n"
230 " waited, _status = os.waitpid(authority.pid, 0)",
231 ),
232 (
233 "child subreaper exact reap removed",
234 PROCESS,
235 "return waited == authority.pid",
236 "return True",
237 ),
238 (
239 "child subreaper empty completion removed",
240 PROCESS,
241 " if _child_table_is_empty():",
242 " if True:",
243 ),
244 )
245
246
247def _process_mutations_3() -> tuple[Mutation, ...]:
248 """Return terminal subreaper completion and fail-stop mutations."""
249 return (
250 (
251 "child subreaper ECHILD completion removed",
252 PROCESS,
253 " except ChildProcessError:\n return True\n return False",
254 " except ChildProcessError:\n return False\n return False",
255 ),
256 (
257 "child subreaper blocking containment removed",
258 PROCESS,
259 " while not cleaned and not self.children_contained:",
260 " if not cleaned and not self.children_contained:",
261 ),
262 )
263
264
265def _cross_source_mutations() -> tuple[Mutation, ...]:
266 """Return exact main-supervisor subreaper call mutations."""
267 return (
268 (
269 "child subreaper enable call removed",
270 SUPERVISOR,
271 " owned_test_descriptor = active.test_descriptor\n"
272 " if not supervisor.enable_subreaper():\n"
273 " return INTEGRITY_REFUSAL_STATUS",
274 " owned_test_descriptor = active.test_descriptor\n"
275 " if False:\n"
276 " return INTEGRITY_REFUSAL_STATUS",
277 ),
278 (
279 "child subreaper final containment call removed",
280 SUPERVISOR,
281 " supervisor.contain()",
282 " supervisor.cleanup()",
283 ),
284 (
285 "closed-controller subreaper enable removed",
286 SUPERVISOR_CASES,
287 " if not supervisor.enable_subreaper():\n return 1\n"
288 ' if mode in ("death", "observation"):',
289 ' if mode in ("death", "observation"):',
290 ),
291 (
292 "closed-controller bound adoption removed",
293 SUPERVISOR_CASES,
294 " supervisor.bind_spawned_child(child)",
295 " supervisor.child, supervisor.pid = child, child.pid",
296 ),
297 (
298 "watchdog pre-proof containment removed",
299 SUPERVISOR_CASES,
300 " contained = supervisor.contain()\n"
301 " _write_exact(\n"
302 " proof_descriptor,\n"
303 ' b"K\\n" if killed and contained else b"F\\n",\n'
304 " RECEIPT_MAX_BYTES,\n"
305 " )",
306 " _write_exact(\n"
307 " proof_descriptor,\n"
308 ' b"K\\n" if killed and contained else b"F\\n",\n'
309 " RECEIPT_MAX_BYTES,\n"
310 " )",
311 ),
312 )
313
314
315def _loader_replacements() -> dict[str, str]:
316 """Return one parseable weakening for each authenticated-loader property."""
317 return {
318 "process source metadata regular binding removed": "True",
319 "process source metadata link binding removed": "True",
320 "process source metadata owner binding removed": "True",
321 "process source metadata group binding removed": "True",
322 "process source metadata mode binding removed": "True",
323 "process source metadata byte bound removed": "metadata.st_size >= 0",
324 "process source read step bound removed": "for _step in (0,):",
325 "process source descriptor pread binding removed": ("chunk = os.read(descriptor, 4096)"),
326 "process source complete-size postcondition removed": "if False:",
327 "process loader bound source read removed": 'source = b""',
328 "process loader pre-exec digest binding removed": "if False:",
329 "process loader namespace name binding removed": ('module_name = "_ra8_unbound_process"'),
330 "process loader private module construction removed": "module = object()",
331 "process loader private module namespace removed": "namespace = {}",
332 "process loader namespace filename binding removed": (
333 'namespace["__file__"] = "process.py"'
334 ),
335 "process loader grant version binding removed": (
336 'namespace["_RA8_SUPERVISOR_PROCESS_VERSION"] = 2'
337 ),
338 "process loader authenticated exec removed": (
339 "eval( # mutation: authenticated exec removed"
340 ),
341 "process loader compile source binding removed": 'compile(b"",',
342 "process loader compile filename binding removed": '"process.py",',
343 "process loader compile exec-mode binding removed": ', "eval")',
344 "process loader grant exact consumption removed": (
345 'grant = namespace.get("_RA8_SUPERVISOR_PROCESS_VERSION")'
346 ),
347 "process loader grant absence postcondition removed": "if False:",
348 "process loader post-exec same-FD digest removed": "if False:",
349 "process loader validation delegation removed": "return ()",
350 "process loader class API binding removed": "if False or not all(",
351 "process loader function API binding removed": "True for value in functions",
352 "process loader API namespace identity removed": "if False:",
353 "process loader class namespace binding removed": "escaped = False",
354 "process loader function namespace binding removed": "escaped = escaped",
355 "process loader method namespace binding removed": "escaped = escaped",
356 "process loader preexisting module refusal removed": "if False:",
357 "process loader module registration removed": "namespace[module_name] = module",
358 "process loader module identity postcondition removed": "escaped = escaped",
359 "process loader module residue cleanup removed": (
360 "if False:\n del sys.modules[module_name]"
361 ),
362 "process loader descriptor final-close removed": "os.fstat(descriptor)",
363 "process loader install residue refusal removed": "if False:",
364 }
365
366
367def _loader_anchor_overrides() -> dict[str, str]:
368 """Return unique contextual anchors for otherwise repeated loader tokens."""
369 metadata_block = (
370 " safe = (\n"
371 " stat.S_ISREG(metadata.st_mode)\n"
372 " and metadata.st_nlink == 1\n"
373 " and metadata.st_uid == os.getuid()\n"
374 " and metadata.st_gid == os.getgid()\n"
375 " and stat.S_IMODE(metadata.st_mode) == PROCESS_MODE\n"
376 " and 0 < metadata.st_size <= PROCESS_MAX_BYTES\n"
377 " )"
378 )
379 pread_block = (
380 " for _step in range(PROCESS_READ_STEPS):\n"
381 " chunk = os.pread(descriptor, 4096, offset)"
382 )
383 exec_block = (
384 " exec( # noqa: S102 -- exact digest-bound source-only FD\n"
385 ' compile(source, namespace["__file__"], "exec"), namespace\n'
386 " )\n"
387 ' grant = namespace.pop("_RA8_SUPERVISOR_PROCESS_VERSION", None)'
388 )
389 close_block = (
390 " if module is not None and sys.modules.get(module_name) is module:\n"
391 " del sys.modules[module_name]\n"
392 " os.close(descriptor)"
393 )
394 overrides = dict.fromkeys(
395 (
396 "process source metadata regular binding removed",
397 "process source metadata link binding removed",
398 "process source metadata owner binding removed",
399 "process source metadata group binding removed",
400 "process source metadata mode binding removed",
401 "process source metadata byte bound removed",
402 ),
403 metadata_block,
404 )
405 overrides["process source descriptor pread binding removed"] = pread_block
406 for label in (
407 "process loader authenticated exec removed",
408 "process loader compile source binding removed",
409 "process loader compile filename binding removed",
410 "process loader compile exec-mode binding removed",
411 ):
412 overrides[label] = exec_block
413 overrides["process loader module residue cleanup removed"] = close_block
414 overrides["process loader descriptor final-close removed"] = close_block
415 return overrides
416
417
418def _loader_mutations() -> tuple[Mutation, ...]:
419 """Return exact mutations for every scoped process-loader authority."""
420 replacements = _loader_replacements()
421 if replacements.keys() != PROCESS_LOADER_TOKENS.keys():
422 message = "process-loader mutation census drifted"
423 raise RuntimeError(message)
424 overrides = _loader_anchor_overrides()
425 mutations = []
426 for label, (_function, token) in PROCESS_LOADER_TOKENS.items():
427 old = overrides.get(label, token)
428 replacement = old.replace(token, replacements[label])
429 mutations.append((label, SUPERVISOR, old, replacement))
430 order_old = (
431 ' namespace["_RA8_SUPERVISOR_PROCESS_VERSION"] = 1\n'
432 " sys.modules[module_name] = module"
433 )
434 order_new = (
435 " sys.modules[module_name] = module\n"
436 ' namespace["_RA8_SUPERVISOR_PROCESS_VERSION"] = 1'
437 )
438 return (
439 *tuple(mutations),
440 ("process loader authentication order changed", SUPERVISOR, order_old, order_new),
441 )
442
443
444def _owner_extraction_mutations() -> tuple[Mutation, ...]:
445 """Require every registered Python and Bash semantic owner to exist exactly once."""
446 owners = (
447 (PROCESS, "BoundGroup._close_entry_authority", " def _close_entry_authority("),
448 (PROCESS, "BoundGroup.spawn", " def spawn("),
449 (SUPERVISOR, "_load_cases_dispatch", "def _load_cases_dispatch("),
450 (SUPERVISOR, "_open_suite_root_authority", "def _open_suite_root_authority("),
451 (SUPERVISOR, "_read_cases_source", "def _read_cases_source("),
452 (SUPERVISOR, "_spawn_payload", "def _spawn_payload("),
453 (SUPERVISOR, "_suite_root_metadata_is_safe", "def _suite_root_metadata_is_safe("),
454 (SUPERVISOR, "_suite_root_path_is_safe", "def _suite_root_path_is_safe("),
455 (SUPERVISOR_CASES, "_closed_controller_command", "def _closed_controller_command("),
456 (
457 SUPERVISOR_CASES,
458 "_closed_controller_descriptor_selftest",
459 "def _closed_controller_descriptor_selftest(",
460 ),
461 (SUPERVISOR_CASES, "_refused_controller_launch", "def _refused_controller_launch("),
462 (SUPERVISOR_CASES, "_suite_root_is_safe", "def _suite_root_is_safe("),
463 (SUPERVISOR_CASES, "_watchdog_expiry_runner", "def _watchdog_expiry_runner("),
464 (_selftest_key, "begin_selftest_spawn_critical", "begin_selftest_spawn_critical() {\n"),
465 (_selftest_key, "finish_selftest_spawn_critical", "finish_selftest_spawn_critical() {\n"),
466 (
467 "devcontainer_image_bound_exit_selftest",
468 "run_bound_exit_supervisor",
469 "run_bound_exit_supervisor() {\n",
470 ),
471 (
472 _selftest_cases_key,
473 "selftest_allocation_signal_path",
474 "selftest_allocation_signal_path() {\n",
475 ),
476 (_signal_selftest_key, "start_signal_controller", "start_signal_controller() {\n"),
477 )
478 mutations = []
479 for key, owner, opening in owners:
480 replacement = "x_" + opening if "() {" in opening else opening.replace("def ", "def x_", 1)
481 mutations.append(
482 (
483 f"semantic owner renamed: {key}:{owner}",
484 key,
485 opening,
486 replacement,
487 )
488 )
489 return tuple(mutations)
490
491
492def _owner_ambiguity_mutations() -> tuple[Mutation, ...]:
493 """Require representative top-level and class owners to remain unambiguous."""
494 return (
495 (
496 f"semantic owner duplicated: {SUPERVISOR_CASES}:_suite_root_is_safe",
497 SUPERVISOR_CASES,
498 "def _entry_belongs_to_root(",
499 "def _suite_root_is_safe(",
500 ),
501 (
502 f"semantic owner duplicated: {PROCESS}:BoundGroup.spawn",
503 PROCESS,
504 " def enable_subreaper(",
505 " def spawn(",
506 ),
507 )
508
509
510def process_authority_mutations() -> tuple[Mutation, ...]:
511 """Return the complete focused process-boundary mutation set."""
512 return (
513 *_process_mutations_1(),
514 *_manual_child_mutations(),
515 *_manual_terminal_mutations(),
516 *_adopted_drain_mutations(),
517 *_process_mutations_2(),
518 *_process_mutations_3(),
519 *_cross_source_mutations(),
520 *_loader_mutations(),
521 *_owner_extraction_mutations(),
522 *_owner_ambiguity_mutations(),
523 )