ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
hil_convergence_safety_runtime_fixtures.py
Go to the documentation of this file.
1# SPDX-License-Identifier: MIT
2# Copyright (c) 2026 Brighton Sikarskie
3"""Source-only process-authority mutations for image-lock runtime checks."""
4
5from __future__ import annotations
6
7Mutation = tuple[str, str, str, str]
8
9SUPERVISOR_BOUND_FINDING = "devcontainer image supervisor: bound cleanup is not load-bearing"
10SUPERVISOR_ORDER_FINDING = "devcontainer image supervisor: cleanup proof order drifted"
11SUPERVISOR_ORDER_ONLY_LABELS = frozenset(
12 {
13 "bound receipt hardlink refusal removed",
14 "bound receipt owner binding removed",
15 "bound receipt mode binding removed",
16 "bound receipt truncation removed",
17 }
18)
19SUPERVISOR_DOUBLE_FINDING_LABELS = frozenset(
20 {
21 "bound-exit parent-death polling removed",
22 "bound-exit controller group cleanup reduced to controller PID",
23 "controller close failure bypasses group KILL",
24 }
25)
26SUPERVISOR_TOKEN_FINDINGS = {
27 "controller root identity binding removed": (
28 "devcontainer image supervisor: required process-authority token is not unique: "
29 "identity == expected_identity"
30 ),
31 "controller root path-shape binding removed": (
32 "devcontainer image supervisor: required process-authority token is not unique: "
33 "_suite_root_path_is_safe(resolved, metadata)"
34 ),
35}
36LIFECYCLE_SEMANTIC_FINDINGS = {
37 "case signal dispatch image lock load removed": (
38 "dev box image lock: fail-closed helper or selftest is not load-bearing"
39 ),
40 "main descriptor basename predicate removed": (
41 "dev box image lock: fail-closed helper or selftest is not load-bearing"
42 ),
43 "main descriptor file and link predicate removed": (
44 "dev box image lock: fail-closed helper or selftest is not load-bearing"
45 ),
46 "main descriptor canonical path predicate removed": (
47 "dev box image lock: fail-closed helper or selftest is not load-bearing"
48 ),
49 "lifecycle helper canonical parent proof removed": (
50 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
51 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
52 '"$SELFTEST_HELPER_PARENT_DIR/devcontainer_image.sh"'
53 ),
54 "lock helper canonical parent proof removed": (
55 "devcontainer image-lock selftest: required process-authority token is not unique: "
56 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
57 '"$SELFTEST_LOCK_HELPER_PARENT_DIR/devcontainer_image.sh"'
58 ),
59 "descriptor-bound wrong entry refusal removed": (
60 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
61 'RA8_SELFTEST_BOUND_ENTRY="$wrong_entry"'
62 ),
63 "descriptor-bound canonical entry proof removed": (
64 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
65 'RA8_SELFTEST_BOUND_ENTRY="$SCRIPT_DIR/devcontainer_image.sh"'
66 ),
67 "group selection explicit success removed": (
68 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
69 'select_selftest_group_id "$tmp" "$rejected" >/dev/null 2>&1 && return 1\n'
70 " done\n return 0"
71 ),
72 "parent-death watchdog selftest removed": (
73 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
74 'run_bound_exit_supervisor --selftest-parent-death "$stall_entry" "$tmp"'
75 ),
76 "live-supervisor watchdog deadline selftest removed": (
77 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
78 'run_bound_exit_supervisor --selftest-watchdog-expiry "$stall_entry" "$tmp"'
79 ),
80 "bound-exit supervisor failure cases removed": (
81 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
82 "selftest_bound_exit_supervisor_failures() {"
83 ),
84 "closed death descriptor selftest removed": (
85 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
86 'run_bound_exit_supervisor --selftest-closed-death-fd "$stall_entry" "$tmp"'
87 ),
88 "hardlink publication group proof removed": (
89 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
90 'run_bound_exit_supervisor --selftest-hardlink-bound "$stall_entry" "$tmp"'
91 ),
92 "missing payload entry proof removed": (
93 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
94 'run_bound_exit_supervisor --selftest-missing-entry "$tmp"'
95 ),
96 "stall fixture descendant marker removed": (
97 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
98 ' "exec -a \\"\\$0\\" /bin/sleep 30" >"$destination") || return 1'
99 ),
100 "nested phase parent identity binding removed": (
101 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
102 'RA8_SELFTEST_NESTED_PARENT_IDENTITY="$SELFTEST_TMP_IDENTITY"'
103 ),
104 "nested phase root receipt binding removed": (
105 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
106 'RA8_SELFTEST_NESTED_ROOT_RECEIPT="$nested_receipt"'
107 ),
108 "supervisor failure payload regressed to full entry": (
109 "devcontainer image lifecycle selftest: required process-authority token is not unique: "
110 'run_bound_exit_supervisor "$stall_entry" "$bound" "$outer"'
111 ),
112}
113SIGNAL_SEMANTIC_FINDINGS = {
114 "signal helper canonical parent proof removed": (
115 "devcontainer image signal selftest: required process-authority token is not unique: "
116 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
117 '"$SELFTEST_SIGNAL_PARENT_DIR/devcontainer_image.sh"',
118 ),
119 "signal controller PID local renamed to controller": (
120 "devcontainer image signal selftest: required process-authority token is not unique: "
121 'local launcher_mode="${5:-}" controller_pid pending '
122 'ready="$3/controller-launcher.ready"',
123 ),
124 "image lock controller group authorization removed": (
125 "devcontainer image signal selftest: required process-authority token is not unique: "
126 'controller_group_signal_is_authorized "$controller" || return 1',
127 ),
128 "image lock controller group target reduced to PID": (
129 "devcontainer image signal selftest: required process-authority token is not unique: "
130 'builtin kill -"$signal" -- "-$controller"',
131 ),
132 "image lock controller group signal reduced to direct PID": (
133 "devcontainer image signal selftest: required process-authority token is not unique: "
134 'signal_owned_controller_group "$signal" "$controller" ||',
135 "image lock receipt: selftest_signal_cleanup completion order drifted",
136 ),
137 "pre-isolation numeric PID regained signal authority": (
138 "devcontainer image signal selftest: required process-authority token is not unique: "
139 'signal_owned_live_child TERM "$controller_pid" || controller_bound_spawn_signal 1',
140 ),
141 "exited pre-isolation child refusal removed": (
142 "devcontainer image signal selftest: required process-authority token is not unique: "
143 '! signal_owned_live_child TERM "$child" || controller_bound_spawn_signal 1',
144 ),
145 "image lock selftest_signal_ready_timeout early success refused": (
146 "image lock receipt: selftest_signal_ready_timeout can return success before its proof",
147 ),
148 "image lock selftest_signal_cleanup early success refused": (
149 "dev box image lock: bounded selftest harness is not load-bearing",
150 "image lock receipt: selftest_signal_cleanup can return success before its proof",
151 ),
152 "image lock signal-ready negative deadline proof removed": (
153 "image lock receipt: selftest_signal_ready_timeout completion order drifted",
154 ),
155 "image lock signal expected status proof removed": (
156 "image lock receipt: selftest_signal_cleanup completion order drifted",
157 ),
158 "image lock signal fallback removed": (
159 "dev box image lock: bounded selftest harness is not load-bearing",
160 ),
161 "image lock unready-controller fallback removed": (
162 "dev box image lock: bounded selftest harness is not load-bearing",
163 ),
164 "fresh case signal process bypassed": (
165 "devcontainer image signal selftest: required process-authority token is not unique: "
166 '--selftest-case-signal-child "$signal" "$tmp" "$SELFTEST_TMP_IDENTITY"',
167 ),
168}
169CASES_SEMANTIC_FINDINGS = {
170 "allocation parent proof call removed": (
171 "devcontainer image cases selftest: required process-authority token is not unique: "
172 'selftest_temp_root_is_safe || die "selftest: allocation parent authority is unsafe"',
173 ),
174 "canonical tmp special-mode proof removed": (
175 "devcontainer image cases selftest: required process-authority token is not unique: "
176 '"$(file_special_mode "$SELFTEST_TMP_ROOT")" == "1777" ]]',
177 ),
178 "nested suite-root safety proof removed": (
179 "devcontainer image cases selftest: required process-authority token is not unique: "
180 '"$SELFTEST_TMP_ROOT_IDENTITY" == "$SELFTEST_SUITE_ROOT_IDENTITY" ]] &&\n'
181 " selftest_suite_root_is_safe",
182 ),
183 "cases helper canonical parent proof removed": (
184 "devcontainer image cases selftest: required process-authority token is not unique: "
185 '"${DEVCONTAINER_SELFTEST_PARENT:-}" == '
186 '"$SELFTEST_CASES_PARENT_DIR/devcontainer_image.sh"',
187 ),
188 "exited pre-isolation child negative not dispatched": (
189 "devcontainer image cases selftest: required process-authority token is not unique: "
190 'selftest_pre_isolation_exit_refusal "$tmp" ||',
191 ),
192 "nested phase parent configuration removed": (
193 "devcontainer image cases selftest: required process-authority token is not unique: "
194 "configure_bound_exit_nested_suite || die",
195 ),
196 "nested phase root publication removed": (
197 "devcontainer image cases selftest: required process-authority token is not unique: "
198 "publish_bound_exit_nested_root || die",
199 ),
200}
201SUPERVISOR_CASES_SEMANTIC_FINDINGS = {
202 "cases root identity binding removed": (
203 "devcontainer image supervisor cases: required process-authority token is not unique: "
204 'f"{opened_identity[0]}:{opened_identity[1]}" != expected_identity',
205 ),
206 "supervisor cases source-only sentinel removed": (
207 "devcontainer image supervisor cases: required process-authority token is not unique: "
208 'globals().get("_RA8_SUPERVISOR_CASES_VERSION")',
209 ),
210 "observation failure injection removed": (
211 "devcontainer image supervisor cases: required process-authority token is not unique: "
212 "observation_injected = True\n _inject_observation_failure()",
213 ),
214}
215
216
217def semantic_findings(label: str, key: str) -> tuple[str, ...] | None:
218 """Return exact diagnostics for source-only runtime mutation fixtures."""
219 expected = None
220 if key == "devcontainer_image_selftest_supervisor":
221 token = SUPERVISOR_TOKEN_FINDINGS.get(label)
222 if token is not None:
223 expected = (token,)
224 elif label in SUPERVISOR_ORDER_ONLY_LABELS:
225 expected = (SUPERVISOR_ORDER_FINDING,)
226 elif label in SUPERVISOR_DOUBLE_FINDING_LABELS:
227 expected = (SUPERVISOR_BOUND_FINDING, SUPERVISOR_ORDER_FINDING)
228 else:
229 expected = (SUPERVISOR_BOUND_FINDING,)
230 elif key == "devcontainer_image_signal_selftest":
231 expected = SIGNAL_SEMANTIC_FINDINGS.get(label)
232 elif key == "devcontainer_image_selftest_cases":
233 expected = CASES_SEMANTIC_FINDINGS.get(label)
234 if expected is None and label.startswith("managed image lock receipt "):
235 expected = ("dev box image lock: fail-closed helper or selftest is not load-bearing",)
236 elif key == "devcontainer_image_selftest_supervisor_cases":
237 expected = SUPERVISOR_CASES_SEMANTIC_FINDINGS.get(label)
238 else:
239 finding = LIFECYCLE_SEMANTIC_FINDINGS.get(label)
240 expected = None if finding is None else (finding,)
241 return expected
242
243
244def _legacy_process_authority_mutations() -> tuple[Mutation, ...]:
245 """Return nested-root and fresh-process semantic mutations."""
246 lifecycle = "devcontainer_image_selftest"
247 cases = "devcontainer_image_selftest_cases"
248 signal_helper = "devcontainer_image_signal_selftest"
249 parent_identity = ' RA8_SELFTEST_NESTED_PARENT_IDENTITY="$SELFTEST_TMP_IDENTITY" \\\n'
250 root_receipt = ' RA8_SELFTEST_NESTED_ROOT_RECEIPT="$nested_receipt" \\\n'
251 supervisor_call = ' if run_bound_exit_supervisor "$stall_entry" "$bound" "$outer" \\\n'
252 full_entry_call = supervisor_call.replace('"$stall_entry"', '"$SELFTEST_IMAGE_ENTRY"')
253 configure = (
254 ' configure_bound_exit_nested_suite || die "selftest: injected parent suite is unsafe"\n'
255 )
256 publish = (
257 ' publish_bound_exit_nested_root || die "selftest: injected nested-root '
258 'receipt failed"\n'
259 )
260 signal_owned = (
261 ' signal_owned_live_child TERM "$controller_pid" || controller_bound_spawn_signal 1\n'
262 )
263 signal_numeric = ' builtin kill -TERM "$controller_pid" || controller_bound_spawn_signal 1\n'
264 exited_refusal = (
265 ' ! signal_owned_live_child TERM "$child" || controller_bound_spawn_signal 1\n'
266 )
267 exited_dispatch = ' selftest_pre_isolation_exit_refusal "$tmp" ||\n'
268 return (
269 ("nested phase parent identity binding removed", lifecycle, parent_identity, ""),
270 ("nested phase root receipt binding removed", lifecycle, root_receipt, ""),
271 (
272 "supervisor failure payload regressed to full entry",
273 lifecycle,
274 supervisor_call,
275 full_entry_call,
276 ),
277 ("nested phase parent configuration removed", cases, configure, ""),
278 ("nested phase root publication removed", cases, publish, " true\n"),
279 (
280 "pre-isolation numeric PID regained signal authority",
281 signal_helper,
282 signal_owned,
283 signal_numeric,
284 ),
285 (
286 "exited pre-isolation child refusal removed",
287 signal_helper,
288 exited_refusal,
289 " true\n",
290 ),
291 (
292 "exited pre-isolation child negative not dispatched",
293 cases,
294 exited_dispatch,
295 " false ||\n",
296 ),
297 )
298
299
300def _root_binding_mutations() -> tuple[Mutation, ...]:
301 """Return exact controller, cases-root, and source-only mutations."""
302 supervisor = "devcontainer_image_selftest_supervisor"
303 cases = "devcontainer_image_selftest_supervisor_cases"
304 identity_source = "identity == expected_identity"
305 path_source = "_suite_root_path_is_safe(resolved, metadata)"
306 cases_source = 'f"{opened_identity[0]}:{opened_identity[1]}" != expected_identity'
307 sentinel_source = 'globals().get("_RA8_SUPERVISOR_CASES_VERSION")'
308 observation_source = "observation_injected = True\n _inject_observation_failure()"
309 observation_replacement = "observation_injected = True\n None"
310 return (
311 ("controller root identity binding removed", supervisor, identity_source, "True"),
312 ("controller root path-shape binding removed", supervisor, path_source, "True"),
313 ("cases root identity binding removed", cases, cases_source, "False"),
314 (
315 "supervisor cases source-only sentinel removed",
316 cases,
317 sentinel_source,
318 "CASES_LOAD_VERSION",
319 ),
320 (
321 "observation failure injection removed",
322 cases,
323 observation_source,
324 observation_replacement,
325 ),
326 )
327
328
329def _receipt_write_mutations() -> tuple[Mutation, ...]:
330 """Return removals of exact receipt/proof writes that must fire policy."""
331 supervisor = "devcontainer_image_selftest_supervisor"
332 cases = "devcontainer_image_selftest_supervisor_cases"
333 identity_call = (
334 " _write_exact(\n"
335 " identity_descriptor,\n"
336 ' f"{supervisor.pid}\\n".encode("ascii"),\n'
337 " RECEIPT_MAX_BYTES,\n"
338 " )"
339 )
340 proof_call = (
341 " _write_exact(\n"
342 " proof_descriptor,\n"
343 ' b"K\\n" if killed and contained else b"F\\n",\n'
344 " RECEIPT_MAX_BYTES,\n"
345 " )"
346 )
347 return (
348 (
349 "exclusive receipt exact-write use removed",
350 supervisor,
351 " _write_exact(descriptor, payload, ENTRY_MAX_BYTES)",
352 " os.write(descriptor, payload)",
353 ),
354 (
355 "watchdog identity receipt exact-write removed",
356 cases,
357 identity_call,
358 ' os.write(identity_descriptor, f"{supervisor.pid}\\n".encode("ascii"))',
359 ),
360 (
361 "watchdog proof receipt exact-write removed",
362 cases,
363 proof_call,
364 ' os.write(proof_descriptor, b"K\\n" if killed and contained else b"F\\n")',
365 ),
366 )
367
368
369def process_authority_mutations() -> tuple[Mutation, ...]:
370 """Return extracted and runtime-root semantic mutation fixtures."""
371 return (
372 *_legacy_process_authority_mutations(),
373 *_root_binding_mutations(),
374 *_receipt_write_mutations(),
375 )