noqt commited on
Commit
dc5e1e2
·
1 Parent(s): 1710b1e

Add native P0 qualification and release identity hardening

Browse files
scripts/build_release.py CHANGED
@@ -121,6 +121,7 @@ def main() -> int:
121
  ROOT / "scripts" / "self_validate.py": "scripts/self_validate.py",
122
  ROOT / "scripts" / "run_autonomous_matrix.py": "scripts/run_autonomous_matrix.py",
123
  ROOT / "scripts" / "run_native_matrix.py": "scripts/run_native_matrix.py",
 
124
  ROOT / "scripts" / "benchmark_overhead.py": "scripts/benchmark_overhead.py",
125
  ROOT / "scripts" / "verify_evidence.py": "scripts/verify_evidence.py",
126
  ROOT / "scripts" / "package_evidence.py": "scripts/package_evidence.py",
 
121
  ROOT / "scripts" / "self_validate.py": "scripts/self_validate.py",
122
  ROOT / "scripts" / "run_autonomous_matrix.py": "scripts/run_autonomous_matrix.py",
123
  ROOT / "scripts" / "run_native_matrix.py": "scripts/run_native_matrix.py",
124
+ ROOT / "scripts" / "run_p0_native.py": "scripts/run_p0_native.py",
125
  ROOT / "scripts" / "benchmark_overhead.py": "scripts/benchmark_overhead.py",
126
  ROOT / "scripts" / "verify_evidence.py": "scripts/verify_evidence.py",
127
  ROOT / "scripts" / "package_evidence.py": "scripts/package_evidence.py",
scripts/install.py CHANGED
@@ -50,6 +50,7 @@ HEARTBEAT_SOCKET = WATCHDOG_RUNTIME / "heartbeat.sock"
50
  WORKLOAD_NAME = "lumi-eggcracker-workload"
51
  TARGETS = (LIB, BIN, ETC, UNIT, WATCHDOG_UNIT, STATE, RUNTIME, WATCHDOG_RUNTIME)
52
  INSTALLER_VERSION = "0.5.0"
 
53
 
54
 
55
  def digest(path: Path) -> str:
@@ -94,13 +95,66 @@ def socket_contract_matches(path: Path, mode: int, gid: int) -> bool:
94
  )
95
 
96
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
97
  def manifest_for(
98
  artifact: Path, descriptor: int, expected_sha256: str
99
  ) -> dict[str, Any]:
100
  path = artifact.parent / "release-manifest.json"
101
- if path.is_symlink() or not path.is_file():
102
- raise RuntimeError("release manifest is missing")
103
- value = json.loads(path.read_text(encoding="utf-8"))
 
 
 
104
  expected = {"artifact", "sha256", "source_archive", "source_archive_sha256", "source_commit", "version"}
105
  actual_sha256 = digest_descriptor(descriptor)
106
  if (
@@ -115,6 +169,8 @@ def manifest_for(
115
  or not value["version"]
116
  or value["version"] != INSTALLER_VERSION
117
  or len(value["source_commit"]) != 40
 
 
118
  ):
119
  raise RuntimeError("release manifest version or source identity is invalid")
120
  version_check = subprocess.run(
 
50
  WORKLOAD_NAME = "lumi-eggcracker-workload"
51
  TARGETS = (LIB, BIN, ETC, UNIT, WATCHDOG_UNIT, STATE, RUNTIME, WATCHDOG_RUNTIME)
52
  INSTALLER_VERSION = "0.5.0"
53
+ MAX_RELEASE_MANIFEST_BYTES = 32 * 1024
54
 
55
 
56
  def digest(path: Path) -> str:
 
95
  )
96
 
97
 
98
+ def read_stable_regular(path: Path, *, maximum: int) -> bytes:
99
+ """Read one bounded non-symlink file through a stable held descriptor."""
100
+ flags = (
101
+ os.O_RDONLY
102
+ | getattr(os, "O_BINARY", 0)
103
+ | getattr(os, "O_CLOEXEC", 0)
104
+ | getattr(os, "O_NOFOLLOW", 0)
105
+ )
106
+ try:
107
+ descriptor = os.open(path, flags)
108
+ except OSError as error:
109
+ raise RuntimeError(f"cannot open release file {path.name}") from error
110
+ try:
111
+ before = os.fstat(descriptor)
112
+ if not stat.S_ISREG(before.st_mode) or not 1 <= before.st_size <= maximum:
113
+ raise RuntimeError(f"release file {path.name} is invalid")
114
+ value = bytearray()
115
+ while len(value) <= maximum:
116
+ block = os.read(descriptor, min(64 * 1024, maximum + 1 - len(value)))
117
+ if not block:
118
+ break
119
+ value.extend(block)
120
+ after = os.fstat(descriptor)
121
+ def identity(item: os.stat_result) -> tuple[int, int, int, int, int]:
122
+ return (
123
+ item.st_dev,
124
+ item.st_ino,
125
+ item.st_size,
126
+ item.st_mtime_ns,
127
+ item.st_ctime_ns,
128
+ )
129
+ if len(value) > maximum or len(value) != before.st_size or identity(before) != identity(after):
130
+ raise RuntimeError(f"release file {path.name} changed during validation")
131
+ return bytes(value)
132
+ finally:
133
+ os.close(descriptor)
134
+
135
+
136
+ def artifact_source_commit(artifact: Path) -> str:
137
+ try:
138
+ with zipfile.ZipFile(artifact) as bundle:
139
+ raw = bundle.read("lumi_eggcracker/build_info.py")
140
+ except (KeyError, OSError, zipfile.BadZipFile) as error:
141
+ raise RuntimeError("release artifact lacks source identity") from error
142
+ match = re.fullmatch(b'SOURCE_COMMIT = "([0-9a-f]{40})"\r?\n', raw)
143
+ if match is None:
144
+ raise RuntimeError("release artifact source identity is invalid")
145
+ return match.group(1).decode("ascii")
146
+
147
+
148
  def manifest_for(
149
  artifact: Path, descriptor: int, expected_sha256: str
150
  ) -> dict[str, Any]:
151
  path = artifact.parent / "release-manifest.json"
152
+ try:
153
+ value = json.loads(
154
+ read_stable_regular(path, maximum=MAX_RELEASE_MANIFEST_BYTES).decode("utf-8")
155
+ )
156
+ except (UnicodeDecodeError, json.JSONDecodeError) as error:
157
+ raise RuntimeError("release manifest is invalid") from error
158
  expected = {"artifact", "sha256", "source_archive", "source_archive_sha256", "source_commit", "version"}
159
  actual_sha256 = digest_descriptor(descriptor)
160
  if (
 
169
  or not value["version"]
170
  or value["version"] != INSTALLER_VERSION
171
  or len(value["source_commit"]) != 40
172
+ or artifact_source_commit(Path(f"/proc/self/fd/{descriptor}"))
173
+ != value["source_commit"]
174
  ):
175
  raise RuntimeError("release manifest version or source identity is invalid")
176
  version_check = subprocess.run(
scripts/run_p0_native.py ADDED
@@ -0,0 +1,1254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Run the release-blocking native Priority-0 adversarial campaigns.
2
+
3
+ The root controller is only an oracle and fixture coordinator. Every target
4
+ process runs as the dedicated workload identity and wins only while it retains
5
+ a complete supported content/runtime profile.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import argparse
11
+ import ctypes
12
+ import fcntl
13
+ import hashlib
14
+ import json
15
+ import mmap
16
+ import os
17
+ import pwd
18
+ import secrets
19
+ import shutil
20
+ import signal
21
+ import subprocess
22
+ import sys
23
+ import time
24
+ from pathlib import Path
25
+ from typing import Any
26
+
27
+ CLI = Path("/usr/local/bin/eggcracker")
28
+ DETECTIONS = Path("/var/lib/lumi-eggcracker/detections")
29
+ POLICY = Path("/etc/lumi-eggcracker/policy.json")
30
+ INSTALLED_ARTIFACT = Path("/usr/local/lib/lumi-eggcracker/lumi-eggcracker.pyz")
31
+ SCHEMA = "lumi-eggcracker.p0-native.v1"
32
+ PROFILE = "content.gguf-llama"
33
+ HOLD_SECONDS = 180
34
+
35
+
36
+ def digest(path: Path) -> str:
37
+ value = hashlib.sha256()
38
+ with path.open("rb") as handle:
39
+ for block in iter(lambda: handle.read(1024 * 1024), b""):
40
+ value.update(block)
41
+ return value.hexdigest()
42
+
43
+
44
+ def gguf(seed: int) -> bytes:
45
+ # Plausible GGUF v3: one tensor, no metadata, plus the minimum tensor
46
+ # prefix required by the bounded public validator.
47
+ return b"GGUF" + (3).to_bytes(4, "little") + (1).to_bytes(
48
+ 8, "little"
49
+ ) + (0).to_bytes(8, "little") + bytes([seed & 0xFF]) * 12
50
+
51
+
52
+ def write_all(descriptor: int, value: bytes) -> None:
53
+ pending = memoryview(value)
54
+ while pending:
55
+ written = os.write(descriptor, pending)
56
+ if written < 1:
57
+ raise OSError("fixture write made no progress")
58
+ pending = pending[written:]
59
+ os.lseek(descriptor, 0, os.SEEK_SET)
60
+
61
+
62
+ def copy_to_descriptor(source: Path, descriptor: int) -> None:
63
+ with source.open("rb") as handle:
64
+ for block in iter(lambda: handle.read(1024 * 1024), b""):
65
+ write_all_at_current_offset(descriptor, block)
66
+ os.lseek(descriptor, 0, os.SEEK_SET)
67
+
68
+
69
+ def write_all_at_current_offset(descriptor: int, value: bytes) -> None:
70
+ pending = memoryview(value)
71
+ while pending:
72
+ written = os.write(descriptor, pending)
73
+ if written < 1:
74
+ raise OSError("fixture write made no progress")
75
+ pending = pending[written:]
76
+
77
+
78
+ def wait_gate(path: Path, timeout: float = 90) -> None:
79
+ deadline = time.monotonic() + timeout
80
+ while time.monotonic() < deadline:
81
+ if path.is_file():
82
+ return
83
+ time.sleep(0.005)
84
+ raise RuntimeError("fixture gate did not open")
85
+
86
+
87
+ def marker(path: Path, value: dict[str, Any]) -> None:
88
+ path.write_text(json.dumps(value, sort_keys=True) + "\n", encoding="utf-8")
89
+
90
+
91
+ def map_runtime(descriptor: int) -> mmap.mmap:
92
+ return mmap.mmap(
93
+ descriptor,
94
+ 0,
95
+ flags=mmap.MAP_PRIVATE,
96
+ prot=mmap.PROT_READ | mmap.PROT_EXEC,
97
+ )
98
+
99
+
100
+ def fixture_evidence(argv: list[str]) -> int:
101
+ parser = argparse.ArgumentParser()
102
+ parser.add_argument("--mode", required=True)
103
+ parser.add_argument("--model", required=True, type=Path)
104
+ parser.add_argument("--runtime", required=True, type=Path)
105
+ parser.add_argument("--gate", required=True, type=Path)
106
+ parser.add_argument("--ready", required=True, type=Path)
107
+ parser.add_argument("--work", required=True, type=Path)
108
+ parser.add_argument("--pre-fds", type=int, default=0)
109
+ parser.add_argument("--post-fds", type=int, default=0)
110
+ parser.add_argument("--decoy-maps", type=int, default=0)
111
+ args = parser.parse_args(argv)
112
+
113
+ descriptors: list[int] = []
114
+ mappings: list[mmap.mmap] = []
115
+ for _ in range(args.pre_fds):
116
+ descriptors.append(os.open("/dev/null", os.O_RDONLY))
117
+ marker(args.ready, {"pid": os.getpid(), "state": "READY"})
118
+ wait_gate(args.gate)
119
+
120
+ if args.mode in {"regular", "high-fd", "high-maps"}:
121
+ model_descriptor = os.open(args.model, os.O_RDONLY)
122
+ elif args.mode in {"memfd-model", "sealed-memfd-model"}:
123
+ flags = getattr(os, "MFD_ALLOW_SEALING", 2)
124
+ model_descriptor = os.memfd_create("p0-model", flags=flags)
125
+ write_all(model_descriptor, args.model.read_bytes())
126
+ if args.mode == "sealed-memfd-model":
127
+ seals = (
128
+ getattr(fcntl, "F_SEAL_SEAL", 0x0001)
129
+ | getattr(fcntl, "F_SEAL_SHRINK", 0x0002)
130
+ | getattr(fcntl, "F_SEAL_GROW", 0x0004)
131
+ | getattr(fcntl, "F_SEAL_WRITE", 0x0008)
132
+ )
133
+ fcntl.fcntl(model_descriptor, getattr(fcntl, "F_ADD_SEALS", 1033), seals)
134
+ elif args.mode == "otmpfile-model":
135
+ model_descriptor = os.open(
136
+ args.work,
137
+ os.O_TMPFILE | os.O_RDWR,
138
+ 0o600,
139
+ )
140
+ write_all(model_descriptor, args.model.read_bytes())
141
+ elif args.mode == "deleted-model":
142
+ private = args.work / f"deleted-model-{os.getpid()}"
143
+ private.write_bytes(args.model.read_bytes())
144
+ model_descriptor = os.open(private, os.O_RDONLY)
145
+ private.unlink()
146
+ elif args.mode == "unlink-model":
147
+ model_descriptor = os.open(args.model, os.O_RDONLY)
148
+ args.model.unlink()
149
+ else:
150
+ model_descriptor = os.open(args.model, os.O_RDONLY)
151
+ descriptors.append(model_descriptor)
152
+
153
+ for _ in range(args.post_fds):
154
+ descriptors.append(os.open("/dev/null", os.O_RDONLY))
155
+ for index in range(args.decoy_maps):
156
+ decoy = args.work / f"map-{os.getpid()}-{index}"
157
+ descriptor = os.open(decoy, os.O_CREAT | os.O_EXCL | os.O_RDWR, 0o600)
158
+ os.ftruncate(descriptor, 4096)
159
+ mappings.append(
160
+ mmap.mmap(
161
+ descriptor,
162
+ 4096,
163
+ flags=mmap.MAP_PRIVATE,
164
+ prot=mmap.PROT_READ | mmap.PROT_EXEC,
165
+ )
166
+ )
167
+ descriptors.append(descriptor)
168
+
169
+ if args.mode in {"memfd-runtime", "otmpfile-runtime", "deleted-runtime", "unlink-runtime"}:
170
+ if args.mode == "memfd-runtime":
171
+ runtime_descriptor = os.memfd_create("p0-runtime", flags=0)
172
+ elif args.mode == "otmpfile-runtime":
173
+ runtime_descriptor = os.open(
174
+ args.work,
175
+ os.O_TMPFILE | os.O_RDWR,
176
+ 0o700,
177
+ )
178
+ elif args.mode == "unlink-runtime":
179
+ runtime_descriptor = os.open(args.runtime, os.O_RDONLY)
180
+ else:
181
+ private_runtime = args.work / f"deleted-runtime-{os.getpid()}"
182
+ shutil.copyfile(args.runtime, private_runtime)
183
+ runtime_descriptor = os.open(private_runtime, os.O_RDONLY)
184
+ private_runtime.unlink()
185
+ if args.mode in {"memfd-runtime", "otmpfile-runtime"}:
186
+ copy_to_descriptor(args.runtime, runtime_descriptor)
187
+ mappings.append(map_runtime(runtime_descriptor))
188
+ descriptors.append(runtime_descriptor)
189
+ if args.mode == "unlink-runtime":
190
+ args.runtime.unlink()
191
+ else:
192
+ runtime_descriptor = os.open(args.runtime, os.O_RDONLY)
193
+ mappings.append(map_runtime(runtime_descriptor))
194
+ descriptors.append(runtime_descriptor)
195
+
196
+ marker(
197
+ args.ready.with_suffix(".armed"),
198
+ {
199
+ "descriptors": len(descriptors),
200
+ "maps": len(mappings),
201
+ "pid": os.getpid(),
202
+ "state": "ARMED",
203
+ },
204
+ )
205
+ time.sleep(HOLD_SECONDS)
206
+ return 0
207
+
208
+
209
+ def fixture_storm(argv: list[str]) -> int:
210
+ parser = argparse.ArgumentParser()
211
+ parser.add_argument("--count", required=True, type=int)
212
+ parser.add_argument("--role", choices=("complete", "content"), required=True)
213
+ parser.add_argument("--model", required=True, type=Path)
214
+ parser.add_argument("--runtime", required=True, type=Path)
215
+ parser.add_argument("--gate", required=True, type=Path)
216
+ parser.add_argument("--ready", required=True, type=Path)
217
+ args = parser.parse_args(argv)
218
+ children: list[int] = []
219
+ for _ in range(args.count):
220
+ pid = os.fork()
221
+ if pid:
222
+ children.append(pid)
223
+ continue
224
+ wait_gate(args.gate)
225
+ descriptors = [os.open(args.model, os.O_RDONLY)]
226
+ mappings: list[mmap.mmap] = []
227
+ if args.role == "complete":
228
+ runtime_descriptor = os.open(args.runtime, os.O_RDONLY)
229
+ descriptors.append(runtime_descriptor)
230
+ mappings.append(map_runtime(runtime_descriptor))
231
+ time.sleep(HOLD_SECONDS)
232
+ os._exit(0)
233
+ marker(
234
+ args.ready,
235
+ {"children": children, "count": len(children), "pid": os.getpid(), "state": "READY"},
236
+ )
237
+ time.sleep(HOLD_SECONDS)
238
+ return 0
239
+
240
+
241
+ def execveat(descriptor: int, command: list[str], environment: dict[str, str]) -> None:
242
+ libc = ctypes.CDLL(None, use_errno=True)
243
+ argv = (ctypes.c_char_p * (len(command) + 1))(
244
+ *(item.encode() for item in command),
245
+ None,
246
+ )
247
+ env_values = [f"{key}={value}".encode() for key, value in environment.items()]
248
+ envp = (ctypes.c_char_p * (len(env_values) + 1))(*env_values, None)
249
+ result = libc.syscall(
250
+ 322, # x86-64 SYS_execveat
251
+ descriptor,
252
+ ctypes.c_char_p(b""),
253
+ argv,
254
+ envp,
255
+ 0x1000, # AT_EMPTY_PATH
256
+ )
257
+ if result != 0:
258
+ error = ctypes.get_errno()
259
+ raise OSError(error, os.strerror(error))
260
+ raise RuntimeError("execveat unexpectedly returned")
261
+
262
+
263
+ def runner_command(executable: str, model: str) -> list[str]:
264
+ return [
265
+ executable,
266
+ "-m",
267
+ model,
268
+ "-p",
269
+ "Name a Linux cgroup property.",
270
+ "-n",
271
+ "4096",
272
+ "-t",
273
+ "4",
274
+ "-tb",
275
+ "4",
276
+ "-c",
277
+ "512",
278
+ "--simple-io",
279
+ "--single-turn",
280
+ "--no-warmup",
281
+ "--no-display-prompt",
282
+ "--ignore-eos",
283
+ "--seed",
284
+ "1234",
285
+ ]
286
+
287
+
288
+ def fixture_exec(argv: list[str]) -> int:
289
+ parser = argparse.ArgumentParser()
290
+ parser.add_argument("--mode", required=True)
291
+ parser.add_argument("--model", required=True, type=Path)
292
+ parser.add_argument("--runtime", required=True, type=Path)
293
+ parser.add_argument("--gate", required=True, type=Path)
294
+ parser.add_argument("--ready", required=True, type=Path)
295
+ parser.add_argument("--work", required=True, type=Path)
296
+ args = parser.parse_args(argv)
297
+ environment = {
298
+ "HOME": "/nonexistent",
299
+ "LANG": "C.UTF-8",
300
+ "PATH": "/usr/bin:/bin",
301
+ }
302
+
303
+ if args.mode in {"procfd-model", "sealed-procfd-model"}:
304
+ flags = getattr(os, "MFD_ALLOW_SEALING", 2)
305
+ model_descriptor = os.memfd_create("p0-real-model", flags=flags)
306
+ copy_to_descriptor(args.model, model_descriptor)
307
+ if args.mode == "sealed-procfd-model":
308
+ seals = (
309
+ getattr(fcntl, "F_SEAL_SEAL", 0x0001)
310
+ | getattr(fcntl, "F_SEAL_SHRINK", 0x0002)
311
+ | getattr(fcntl, "F_SEAL_GROW", 0x0004)
312
+ | getattr(fcntl, "F_SEAL_WRITE", 0x0008)
313
+ )
314
+ fcntl.fcntl(model_descriptor, getattr(fcntl, "F_ADD_SEALS", 1033), seals)
315
+ os.set_inheritable(model_descriptor, True)
316
+ marker(args.ready, {"pid": os.getpid(), "state": "READY"})
317
+ wait_gate(args.gate)
318
+ model = f"/proc/self/fd/{model_descriptor}"
319
+ os.execve(args.runtime, runner_command(str(args.runtime), model), environment)
320
+
321
+ if args.mode in {"memfd-exec", "execveat-memfd"}:
322
+ runtime_descriptor = os.memfd_create("p0-executable", flags=0)
323
+ elif args.mode == "otmpfile-exec":
324
+ runtime_descriptor = os.open(args.work, os.O_TMPFILE | os.O_RDWR, 0o700)
325
+ elif args.mode == "deleted-exec":
326
+ private = args.work / f"deleted-exec-{os.getpid()}"
327
+ shutil.copyfile(args.runtime, private)
328
+ os.chmod(private, 0o700)
329
+ runtime_descriptor = os.open(private, os.O_RDONLY)
330
+ private.unlink()
331
+ else:
332
+ raise RuntimeError("unknown pathless execution mode")
333
+ if args.mode != "deleted-exec":
334
+ copy_to_descriptor(args.runtime, runtime_descriptor)
335
+ os.fchmod(runtime_descriptor, 0o700)
336
+ marker(args.ready, {"pid": os.getpid(), "state": "READY"})
337
+ wait_gate(args.gate)
338
+ command = runner_command("p0-pathless-runtime", str(args.model))
339
+ if args.mode == "execveat-memfd":
340
+ execveat(runtime_descriptor, command, environment)
341
+ os.execve(runtime_descriptor, command, environment)
342
+ raise RuntimeError("fexecve unexpectedly returned")
343
+
344
+
345
+ def control(argv: list[str], *, operator: str | None = None, environment: dict[str, str] | None = None) -> tuple[int, str, str]:
346
+ command = [str(CLI), *argv]
347
+ if operator is not None:
348
+ command = ["/usr/sbin/runuser", "-u", operator, "--", *command]
349
+ result = subprocess.run(
350
+ command,
351
+ capture_output=True,
352
+ text=True,
353
+ check=False,
354
+ timeout=60,
355
+ env=environment,
356
+ )
357
+ return result.returncode, result.stdout, result.stderr
358
+
359
+
360
+ def json_control(argv: list[str], *, operator: str | None = None) -> dict[str, Any]:
361
+ code, stdout, stderr = control(argv, operator=operator)
362
+ if code:
363
+ raise RuntimeError(stderr.strip() or stdout.strip() or "Eggcracker control failed")
364
+ value = json.loads(stdout)
365
+ if not isinstance(value, dict):
366
+ raise RuntimeError("Eggcracker control response is invalid")
367
+ return value
368
+
369
+
370
+ def stop(process: subprocess.Popen[bytes] | None) -> None:
371
+ if process is None or process.poll() is not None:
372
+ return
373
+ try:
374
+ os.killpg(process.pid, signal.SIGKILL)
375
+ except ProcessLookupError:
376
+ pass
377
+ try:
378
+ process.wait(timeout=10)
379
+ except subprocess.TimeoutExpired:
380
+ process.kill()
381
+ process.wait(timeout=5)
382
+
383
+
384
+ def alive(pid: int) -> bool:
385
+ try:
386
+ fields = Path(f"/proc/{pid}/stat").read_text(encoding="ascii").split()
387
+ except OSError:
388
+ return False
389
+ return len(fields) > 2 and fields[2] != "Z"
390
+
391
+
392
+ def wait_ready(path: Path, timeout: float = 90) -> dict[str, Any]:
393
+ deadline = time.monotonic() + timeout
394
+ while time.monotonic() < deadline:
395
+ try:
396
+ value = json.loads(path.read_text(encoding="utf-8"))
397
+ except (OSError, json.JSONDecodeError):
398
+ time.sleep(0.01)
399
+ continue
400
+ if isinstance(value, dict):
401
+ return value
402
+ raise RuntimeError(f"fixture readiness failed for {path.name}")
403
+
404
+
405
+ def receipts_after(before: set[Path]) -> list[dict[str, Any]]:
406
+ result: list[dict[str, Any]] = []
407
+ for path in sorted(set(DETECTIONS.glob("*.json")) - before):
408
+ result.append(json.loads(path.read_text(encoding="utf-8")))
409
+ return result
410
+
411
+
412
+ def validate_receipts(
413
+ values: list[dict[str, Any]],
414
+ *,
415
+ expected: int,
416
+ source_commit: str,
417
+ ) -> list[float]:
418
+ if len(values) != expected:
419
+ raise RuntimeError(f"expected {expected} receipts, observed {len(values)}")
420
+ latencies: list[float] = []
421
+ event_ids: set[str] = set()
422
+ for value in values:
423
+ containment = value.get("containment", {})
424
+ if (
425
+ value.get("result") != "TERMINATED"
426
+ or value.get("source_commit") != source_commit
427
+ or value.get("detector", {}).get("profile") != PROFILE
428
+ or containment.get("root_populated") != 0
429
+ or containment.get("surviving_pids") != []
430
+ or "cgroup.kill" not in str(containment.get("primitive"))
431
+ ):
432
+ raise RuntimeError("receipt did not prove exact supported-profile containment")
433
+ event_id = value.get("event_id")
434
+ if not isinstance(event_id, str) or event_id in event_ids:
435
+ raise RuntimeError("receipt event identity is invalid or duplicated")
436
+ event_ids.add(event_id)
437
+ latencies.append(float(containment["trigger_to_empty_ms"]))
438
+ return latencies
439
+
440
+
441
+ def launch_fixture(
442
+ script: Path,
443
+ workload: str,
444
+ subcommand: str,
445
+ arguments: list[str],
446
+ ) -> subprocess.Popen[bytes]:
447
+ return subprocess.Popen(
448
+ [
449
+ "/usr/sbin/runuser",
450
+ "-u",
451
+ workload,
452
+ "--",
453
+ "/usr/bin/python3",
454
+ "-I",
455
+ "-S",
456
+ str(script),
457
+ subcommand,
458
+ *arguments,
459
+ ],
460
+ stdout=subprocess.DEVNULL,
461
+ stderr=subprocess.DEVNULL,
462
+ start_new_session=True,
463
+ )
464
+
465
+
466
+ def wait_for_kills(
467
+ processes: list[subprocess.Popen[bytes]],
468
+ target_pids: list[int],
469
+ before: set[Path],
470
+ expected: int,
471
+ timeout: float,
472
+ ) -> list[dict[str, Any]]:
473
+ deadline = time.monotonic() + timeout
474
+ while time.monotonic() < deadline:
475
+ values = receipts_after(before)
476
+ if len(values) >= expected and not any(alive(pid) for pid in target_pids):
477
+ for process in processes:
478
+ try:
479
+ process.wait(timeout=5)
480
+ except subprocess.TimeoutExpired:
481
+ pass
482
+ return values
483
+ time.sleep(0.05)
484
+ raise RuntimeError(
485
+ f"containment timed out: receipts={len(receipts_after(before))}, "
486
+ f"survivors={sum(alive(pid) for pid in target_pids)}"
487
+ )
488
+
489
+
490
+ class Campaign:
491
+ def __init__(
492
+ self,
493
+ *,
494
+ script: Path,
495
+ workload: str,
496
+ operator: str,
497
+ runtime: Path,
498
+ real_model: Path,
499
+ output: Path,
500
+ ) -> None:
501
+ self.script = script
502
+ self.workload = workload
503
+ self.operator = operator
504
+ self.runtime = runtime
505
+ self.real_model = real_model
506
+ self.output = output
507
+ self.policy = json.loads(POLICY.read_text(encoding="utf-8"))
508
+ token = secrets.token_hex(8)
509
+ self.root = Path(f"/opt/lumi-eggcracker-p0-{token}")
510
+ self.work = self.root / "work"
511
+ self.root.mkdir(mode=0o755)
512
+ self.work.mkdir(mode=0o733)
513
+ os.chmod(self.work, 0o733)
514
+ self.model = self.root / "synthetic.gguf"
515
+ self.model.write_bytes(gguf(1))
516
+ self.model.chmod(0o444)
517
+ self.canary = subprocess.Popen(
518
+ ["/usr/sbin/runuser", "-u", workload, "--", "/bin/sleep", "900"],
519
+ stdout=subprocess.DEVNULL,
520
+ stderr=subprocess.DEVNULL,
521
+ start_new_session=True,
522
+ )
523
+ self.results: dict[str, Any] = {
524
+ "approval_material_substitution": [],
525
+ "pathless_deleted": [],
526
+ "saturation": [],
527
+ }
528
+
529
+ def assert_canary(self) -> None:
530
+ if self.canary.poll() is not None:
531
+ raise RuntimeError("unrelated workload-identity canary was terminated")
532
+
533
+ def doctor(self) -> dict[str, Any]:
534
+ value = json_control(["doctor"])
535
+ if value.get("result") != "PASS":
536
+ raise RuntimeError("Eggcracker health did not recover to PASS")
537
+ return value
538
+
539
+ def one_evidence(
540
+ self,
541
+ mode: str,
542
+ *,
543
+ model: Path | None = None,
544
+ runtime: Path | None = None,
545
+ pre_fds: int = 0,
546
+ post_fds: int = 0,
547
+ decoy_maps: int = 0,
548
+ timeout: float = 90,
549
+ ) -> dict[str, Any]:
550
+ token = secrets.token_hex(6)
551
+ gate = self.root / f"gate-{token}"
552
+ ready = self.work / f"ready-{token}.json"
553
+ before = set(DETECTIONS.glob("*.json"))
554
+ process = launch_fixture(
555
+ self.script,
556
+ self.workload,
557
+ "fixture-evidence",
558
+ [
559
+ "--mode",
560
+ mode,
561
+ "--model",
562
+ str(model or self.model),
563
+ "--runtime",
564
+ str(runtime or self.runtime),
565
+ "--gate",
566
+ str(gate),
567
+ "--ready",
568
+ str(ready),
569
+ "--work",
570
+ str(self.work),
571
+ "--pre-fds",
572
+ str(pre_fds),
573
+ "--post-fds",
574
+ str(post_fds),
575
+ "--decoy-maps",
576
+ str(decoy_maps),
577
+ ],
578
+ )
579
+ try:
580
+ identity = wait_ready(ready)
581
+ gate.write_bytes(b"go\n")
582
+ gate.chmod(0o444)
583
+ receipts = wait_for_kills(
584
+ [process],
585
+ [int(identity["pid"])],
586
+ before,
587
+ 1,
588
+ timeout,
589
+ )
590
+ latencies = validate_receipts(
591
+ receipts,
592
+ expected=1,
593
+ source_commit=self.policy["source_commit"],
594
+ )
595
+ self.assert_canary()
596
+ return {
597
+ "case": mode,
598
+ "result": "PASS",
599
+ "trigger_to_empty_ms": latencies[0],
600
+ }
601
+ finally:
602
+ stop(process)
603
+
604
+ def one_exec(self, mode: str, timeout: float = 150) -> dict[str, Any]:
605
+ token = secrets.token_hex(6)
606
+ gate = self.root / f"gate-{token}"
607
+ ready = self.work / f"ready-{token}.json"
608
+ before = set(DETECTIONS.glob("*.json"))
609
+ process = launch_fixture(
610
+ self.script,
611
+ self.workload,
612
+ "fixture-exec",
613
+ [
614
+ "--mode",
615
+ mode,
616
+ "--model",
617
+ str(self.real_model),
618
+ "--runtime",
619
+ str(self.runtime),
620
+ "--gate",
621
+ str(gate),
622
+ "--ready",
623
+ str(ready),
624
+ "--work",
625
+ str(self.work),
626
+ ],
627
+ )
628
+ try:
629
+ identity = wait_ready(ready, timeout=120)
630
+ gate.write_bytes(b"go\n")
631
+ gate.chmod(0o444)
632
+ receipts = wait_for_kills(
633
+ [process],
634
+ [int(identity["pid"])],
635
+ before,
636
+ 1,
637
+ timeout,
638
+ )
639
+ latencies = validate_receipts(
640
+ receipts,
641
+ expected=1,
642
+ source_commit=self.policy["source_commit"],
643
+ )
644
+ self.assert_canary()
645
+ return {
646
+ "case": mode,
647
+ "result": "PASS",
648
+ "trigger_to_empty_ms": latencies[0],
649
+ }
650
+ finally:
651
+ stop(process)
652
+
653
+ def wave(self, count: int) -> dict[str, Any]:
654
+ token = secrets.token_hex(6)
655
+ gate = self.root / f"wave-gate-{token}"
656
+ before = set(DETECTIONS.glob("*.json"))
657
+ processes: list[subprocess.Popen[bytes]] = []
658
+ ready_paths: list[Path] = []
659
+ try:
660
+ for index in range(count):
661
+ ready = self.work / f"wave-{token}-{index}.json"
662
+ ready_paths.append(ready)
663
+ processes.append(
664
+ launch_fixture(
665
+ self.script,
666
+ self.workload,
667
+ "fixture-evidence",
668
+ [
669
+ "--mode",
670
+ "regular",
671
+ "--model",
672
+ str(self.model),
673
+ "--runtime",
674
+ str(self.runtime),
675
+ "--gate",
676
+ str(gate),
677
+ "--ready",
678
+ str(ready),
679
+ "--work",
680
+ str(self.work),
681
+ ],
682
+ )
683
+ )
684
+ identities = [wait_ready(path) for path in ready_paths]
685
+ gate.write_bytes(b"go\n")
686
+ gate.chmod(0o444)
687
+ receipts = wait_for_kills(
688
+ processes,
689
+ [int(item["pid"]) for item in identities],
690
+ before,
691
+ count,
692
+ 120,
693
+ )
694
+ latencies = validate_receipts(
695
+ receipts,
696
+ expected=count,
697
+ source_commit=self.policy["source_commit"],
698
+ )
699
+ self.assert_canary()
700
+ return {
701
+ "case": f"unrelated-complete-wave-{count}",
702
+ "max_trigger_to_empty_ms": max(latencies),
703
+ "receipts": len(receipts),
704
+ "result": "PASS",
705
+ }
706
+ finally:
707
+ for process in processes:
708
+ stop(process)
709
+
710
+ def storm(self, count: int, role: str) -> dict[str, Any]:
711
+ token = secrets.token_hex(6)
712
+ gate = self.root / f"storm-gate-{token}"
713
+ ready = self.work / f"storm-{token}.json"
714
+ before = set(DETECTIONS.glob("*.json"))
715
+ process = launch_fixture(
716
+ self.script,
717
+ self.workload,
718
+ "fixture-storm",
719
+ [
720
+ "--count",
721
+ str(count),
722
+ "--role",
723
+ role,
724
+ "--model",
725
+ str(self.model),
726
+ "--runtime",
727
+ str(self.runtime),
728
+ "--gate",
729
+ str(gate),
730
+ "--ready",
731
+ str(ready),
732
+ ],
733
+ )
734
+ try:
735
+ identity = wait_ready(ready)
736
+ children = [int(item) for item in identity["children"]]
737
+ if len(children) != count:
738
+ raise RuntimeError("storm did not create the requested process count")
739
+ gate.write_bytes(b"go\n")
740
+ gate.chmod(0o444)
741
+ if role == "complete":
742
+ receipts = wait_for_kills(
743
+ [process],
744
+ [int(identity["pid"]), *children],
745
+ before,
746
+ 1,
747
+ 120,
748
+ )
749
+ validate_receipts(
750
+ receipts,
751
+ expected=1,
752
+ source_commit=self.policy["source_commit"],
753
+ )
754
+ if int(receipts[0].get("capture", {}).get("captured_processes", 0)) < count + 1:
755
+ raise RuntimeError("related component receipt omitted armed processes")
756
+ else:
757
+ time.sleep(12)
758
+ if receipts_after(before) or not all(alive(pid) for pid in children):
759
+ raise RuntimeError("partial-profile storm was killed or produced a receipt")
760
+ self.assert_canary()
761
+ return {
762
+ "case": f"related-{role}-storm-{count}",
763
+ "processes": count,
764
+ "receipts": len(receipts_after(before)),
765
+ "result": "PASS",
766
+ }
767
+ finally:
768
+ stop(process)
769
+
770
+ def reject_mutation(self, kind: str) -> dict[str, Any]:
771
+ root = self.root / f"approval-{kind}-{secrets.token_hex(4)}"
772
+ root.mkdir(mode=0o755)
773
+ model = root / "model.gguf"
774
+ hostile = root / "hostile.gguf"
775
+ model.write_bytes(gguf(10))
776
+ hostile.write_bytes(gguf(20))
777
+ model.chmod(0o444)
778
+ hostile.chmod(0o444)
779
+ name = f"p0-{kind}-{secrets.token_hex(4)}"
780
+ run_name = f"p0-run-{kind}-{secrets.token_hex(4)}"
781
+ command = [str(self.runtime), "-m", str(model), "--version"]
782
+ json_control(
783
+ [
784
+ "approve",
785
+ "--name",
786
+ name,
787
+ "--uid",
788
+ str(self.policy["workload_uid"]),
789
+ "--",
790
+ *command,
791
+ ]
792
+ )
793
+ mounted = False
794
+ try:
795
+ if kind == "rename":
796
+ os.replace(hostile, model)
797
+ elif kind == "hardlink":
798
+ model.unlink()
799
+ os.link(hostile, model)
800
+ elif kind == "symlink":
801
+ model.unlink()
802
+ model.symlink_to(hostile)
803
+ elif kind == "exchange":
804
+ libc = ctypes.CDLL(None, use_errno=True)
805
+ result = libc.renameat2(
806
+ -100,
807
+ os.fsencode(model),
808
+ -100,
809
+ os.fsencode(hostile),
810
+ 2,
811
+ )
812
+ if result:
813
+ error = ctypes.get_errno()
814
+ raise OSError(error, os.strerror(error))
815
+ elif kind == "bind":
816
+ result = subprocess.run(
817
+ ["/usr/bin/mount", "--bind", str(hostile), str(model)],
818
+ capture_output=True,
819
+ text=True,
820
+ check=False,
821
+ timeout=30,
822
+ )
823
+ if result.returncode:
824
+ raise RuntimeError(result.stderr.strip() or "bind mount failed")
825
+ mounted = True
826
+ else:
827
+ raise RuntimeError("unknown approval substitution")
828
+ code, _stdout, _stderr = control(
829
+ [
830
+ "start",
831
+ "--name",
832
+ run_name,
833
+ "--max-pids",
834
+ "32",
835
+ "--max-memory-mib",
836
+ "1024",
837
+ "--cpu-quota-percent",
838
+ "400",
839
+ "--",
840
+ *command,
841
+ ],
842
+ operator=self.operator,
843
+ )
844
+ if code == 0:
845
+ raise RuntimeError(f"{kind} material substitution inherited approval")
846
+ self.assert_canary()
847
+ return {"case": f"model-{kind}-substitution", "result": "PASS"}
848
+ finally:
849
+ if mounted:
850
+ subprocess.run(
851
+ ["/usr/bin/umount", str(model)],
852
+ capture_output=True,
853
+ check=False,
854
+ timeout=30,
855
+ )
856
+ control(["revoke", "--name", name])
857
+
858
+ def overlay_mutation(self) -> dict[str, Any]:
859
+ root = self.root / f"overlay-{secrets.token_hex(4)}"
860
+ lower, upper, work, merged = (
861
+ root / "lower",
862
+ root / "upper",
863
+ root / "work",
864
+ root / "merged",
865
+ )
866
+ for path in (lower, upper, work, merged):
867
+ path.mkdir(parents=True, mode=0o755)
868
+ model = lower / "model.gguf"
869
+ model.write_bytes(gguf(30))
870
+ model.chmod(0o444)
871
+ result = subprocess.run(
872
+ [
873
+ "/usr/bin/mount",
874
+ "-t",
875
+ "overlay",
876
+ "overlay",
877
+ "-o",
878
+ f"lowerdir={lower},upperdir={upper},workdir={work}",
879
+ str(merged),
880
+ ],
881
+ capture_output=True,
882
+ text=True,
883
+ check=False,
884
+ timeout=30,
885
+ )
886
+ if result.returncode:
887
+ raise RuntimeError(result.stderr.strip() or "overlay mount failed")
888
+ name = f"p0-overlay-{secrets.token_hex(4)}"
889
+ run_name = f"p0-run-overlay-{secrets.token_hex(4)}"
890
+ merged_model = merged / "model.gguf"
891
+ command = [str(self.runtime), "-m", str(merged_model), "--version"]
892
+ try:
893
+ json_control(
894
+ [
895
+ "approve",
896
+ "--name",
897
+ name,
898
+ "--uid",
899
+ str(self.policy["workload_uid"]),
900
+ "--",
901
+ *command,
902
+ ]
903
+ )
904
+ merged_model.chmod(0o644)
905
+ merged_model.write_bytes(gguf(31))
906
+ merged_model.chmod(0o444)
907
+ code, _stdout, _stderr = control(
908
+ [
909
+ "start",
910
+ "--name",
911
+ run_name,
912
+ "--max-pids",
913
+ "32",
914
+ "--max-memory-mib",
915
+ "1024",
916
+ "--cpu-quota-percent",
917
+ "400",
918
+ "--",
919
+ *command,
920
+ ],
921
+ operator=self.operator,
922
+ )
923
+ if code == 0:
924
+ raise RuntimeError("overlay material substitution inherited approval")
925
+ return {"case": "model-overlay-copy-up-substitution", "result": "PASS"}
926
+ finally:
927
+ control(["revoke", "--name", name])
928
+ subprocess.run(
929
+ ["/usr/bin/umount", str(merged)],
930
+ capture_output=True,
931
+ check=False,
932
+ timeout=30,
933
+ )
934
+
935
+ def environment_injection(self) -> dict[str, Any]:
936
+ root = self.root / f"environment-{secrets.token_hex(4)}"
937
+ inputs, outputs, hostile = root / "inputs", root / "outputs", root / "hostile"
938
+ inputs.mkdir(parents=True, mode=0o755)
939
+ outputs.mkdir(mode=0o733)
940
+ hostile.mkdir(mode=0o755)
941
+ os.chmod(outputs, 0o733)
942
+ script = inputs / "approved.py"
943
+ output = outputs / "result"
944
+ marker_path = outputs / "sitecustomize-loaded"
945
+ script.write_text(
946
+ "import pathlib,time\n"
947
+ "try:\n import p0_untrusted\n state='UNSAFE'\n"
948
+ "except ModuleNotFoundError:\n state='SAFE'\n"
949
+ f"pathlib.Path({str(output)!r}).write_text(state)\n"
950
+ "time.sleep(120)\n",
951
+ encoding="utf-8",
952
+ )
953
+ script.chmod(0o444)
954
+ (hostile / "p0_untrusted.py").write_text("VALUE='hostile'\n", encoding="utf-8")
955
+ (hostile / "sitecustomize.py").write_text(
956
+ f"open({str(marker_path)!r},'w').write('loaded')\n",
957
+ encoding="utf-8",
958
+ )
959
+ python = Path("/opt/lumi-eggcracker-torch-smoke/bin/python")
960
+ command = [str(python), str(script), str(output)]
961
+ name = f"p0-env-{secrets.token_hex(4)}"
962
+ run_name = f"p0-run-env-{secrets.token_hex(4)}"
963
+ json_control(
964
+ [
965
+ "approve",
966
+ "--name",
967
+ name,
968
+ "--uid",
969
+ str(self.policy["workload_uid"]),
970
+ "--",
971
+ *command,
972
+ ]
973
+ )
974
+ started = False
975
+ try:
976
+ environment = dict(os.environ)
977
+ environment.update(
978
+ {
979
+ "BASH_ENV": str(hostile / "sitecustomize.py"),
980
+ "LD_AUDIT": "/definitely/absent.so",
981
+ "LD_LIBRARY_PATH": str(hostile),
982
+ "LD_PRELOAD": "/definitely/absent.so",
983
+ "PYTHONPATH": str(hostile),
984
+ "PYTHONSTARTUP": str(hostile / "sitecustomize.py"),
985
+ "PYTHONUSERBASE": str(hostile),
986
+ }
987
+ )
988
+ code, stdout, stderr = control(
989
+ [
990
+ "start",
991
+ "--name",
992
+ run_name,
993
+ "--max-pids",
994
+ "32",
995
+ "--max-memory-mib",
996
+ "1024",
997
+ "--cpu-quota-percent",
998
+ "400",
999
+ "--",
1000
+ *command,
1001
+ ],
1002
+ operator=self.operator,
1003
+ environment=environment,
1004
+ )
1005
+ if code:
1006
+ raise RuntimeError(stderr.strip() or stdout.strip() or "approved start failed")
1007
+ started = True
1008
+ deadline = time.monotonic() + 30
1009
+ while time.monotonic() < deadline and not output.is_file():
1010
+ time.sleep(0.02)
1011
+ if output.read_text(encoding="utf-8") != "SAFE" or marker_path.exists():
1012
+ raise RuntimeError("operator-controlled launch environment reached the workload")
1013
+ return {"case": "python-loader-and-import-environment-injection", "result": "PASS"}
1014
+ finally:
1015
+ if started:
1016
+ receipt = self.work / f"operator-{secrets.token_hex(6)}.json"
1017
+ control(
1018
+ ["kill", "--name", run_name, "--receipt", str(receipt)],
1019
+ operator=self.operator,
1020
+ )
1021
+ receipt.unlink(missing_ok=True)
1022
+ control(["revoke", "--name", name])
1023
+
1024
+ def approved_parent_unapproved_child(self) -> dict[str, Any]:
1025
+ root = self.root / f"parent-child-{secrets.token_hex(4)}"
1026
+ root.mkdir(mode=0o755)
1027
+ gate = root / "gate"
1028
+ gate.write_bytes(b"go\n")
1029
+ gate.chmod(0o444)
1030
+ ready = self.work / f"parent-child-{secrets.token_hex(4)}.json"
1031
+ parent = root / "approved-parent.py"
1032
+ parent.write_text(
1033
+ "import subprocess,time\n"
1034
+ "subprocess.Popen("
1035
+ + repr(
1036
+ [
1037
+ "/usr/bin/python3",
1038
+ "-I",
1039
+ "-S",
1040
+ str(self.script),
1041
+ "fixture-evidence",
1042
+ "--mode",
1043
+ "regular",
1044
+ "--model",
1045
+ str(self.model),
1046
+ "--runtime",
1047
+ str(self.runtime),
1048
+ "--gate",
1049
+ str(gate),
1050
+ "--ready",
1051
+ str(ready),
1052
+ "--work",
1053
+ str(self.work),
1054
+ ]
1055
+ )
1056
+ + ")\n"
1057
+ "time.sleep(120)\n",
1058
+ encoding="utf-8",
1059
+ )
1060
+ parent.chmod(0o444)
1061
+ python = Path("/opt/lumi-eggcracker-torch-smoke/bin/python")
1062
+ command = [str(python), str(parent)]
1063
+ name = f"p0-parent-{secrets.token_hex(4)}"
1064
+ run_name = f"p0-run-parent-{secrets.token_hex(4)}"
1065
+ json_control(
1066
+ [
1067
+ "approve",
1068
+ "--name",
1069
+ name,
1070
+ "--uid",
1071
+ str(self.policy["workload_uid"]),
1072
+ "--",
1073
+ *command,
1074
+ ]
1075
+ )
1076
+ before = set(DETECTIONS.glob("*.json"))
1077
+ started = False
1078
+ try:
1079
+ response = json_control(
1080
+ [
1081
+ "start",
1082
+ "--name",
1083
+ run_name,
1084
+ "--max-pids",
1085
+ "64",
1086
+ "--max-memory-mib",
1087
+ "2048",
1088
+ "--cpu-quota-percent",
1089
+ "400",
1090
+ "--",
1091
+ *command,
1092
+ ],
1093
+ operator=self.operator,
1094
+ )
1095
+ started = True
1096
+ if response.get("state") != "RUNNING":
1097
+ raise RuntimeError("approved parent did not start")
1098
+ wait_ready(ready)
1099
+ deadline = time.monotonic() + 90
1100
+ receipts: list[dict[str, Any]] = []
1101
+ while time.monotonic() < deadline:
1102
+ receipts = receipts_after(before)
1103
+ if receipts:
1104
+ break
1105
+ time.sleep(0.05)
1106
+ validate_receipts(
1107
+ receipts,
1108
+ expected=1,
1109
+ source_commit=self.policy["source_commit"],
1110
+ )
1111
+ status = json_control(["status", "--name", run_name], operator=self.operator)
1112
+ if status.get("state") != "TERMINATED":
1113
+ raise RuntimeError("approved parent survived its unapproved supported child")
1114
+ started = False
1115
+ self.assert_canary()
1116
+ return {"case": "approved-parent-unapproved-supported-child", "result": "PASS"}
1117
+ finally:
1118
+ if started:
1119
+ receipt = self.work / f"operator-{secrets.token_hex(6)}.json"
1120
+ control(
1121
+ ["kill", "--name", run_name, "--receipt", str(receipt)],
1122
+ operator=self.operator,
1123
+ )
1124
+ receipt.unlink(missing_ok=True)
1125
+ control(["revoke", "--name", name])
1126
+
1127
+ def run(self) -> dict[str, Any]:
1128
+ self.doctor()
1129
+ for kind in ("rename", "exchange", "hardlink", "symlink", "bind"):
1130
+ self.results["approval_material_substitution"].append(
1131
+ self.reject_mutation(kind)
1132
+ )
1133
+ self.results["approval_material_substitution"].append(self.overlay_mutation())
1134
+ self.results["approval_material_substitution"].append(
1135
+ self.environment_injection()
1136
+ )
1137
+ self.results["approval_material_substitution"].append(
1138
+ self.approved_parent_unapproved_child()
1139
+ )
1140
+
1141
+ for mode in (
1142
+ "memfd-model",
1143
+ "sealed-memfd-model",
1144
+ "otmpfile-model",
1145
+ "deleted-model",
1146
+ "memfd-runtime",
1147
+ "otmpfile-runtime",
1148
+ "deleted-runtime",
1149
+ ):
1150
+ self.results["pathless_deleted"].append(self.one_evidence(mode))
1151
+ for mode in (
1152
+ "memfd-exec",
1153
+ "execveat-memfd",
1154
+ "otmpfile-exec",
1155
+ "deleted-exec",
1156
+ "procfd-model",
1157
+ "sealed-procfd-model",
1158
+ ):
1159
+ self.results["pathless_deleted"].append(self.one_exec(mode))
1160
+
1161
+ for count in (17, 32, 64):
1162
+ self.results["saturation"].append(self.wave(count))
1163
+ self.results["saturation"].append(self.storm(96, "complete"))
1164
+ self.results["saturation"].append(self.storm(512, "content"))
1165
+ self.results["saturation"].append(
1166
+ self.one_evidence("high-fd", pre_fds=700, post_fds=324, timeout=120)
1167
+ )
1168
+ self.results["saturation"].append(
1169
+ self.one_evidence("high-maps", decoy_maps=600, timeout=180)
1170
+ )
1171
+ final_doctor = self.doctor()
1172
+ self.assert_canary()
1173
+ return {
1174
+ "artifact_sha256": digest(INSTALLED_ARTIFACT),
1175
+ "doctor": final_doctor,
1176
+ "families": self.results,
1177
+ "result": "PASS",
1178
+ "schema_version": SCHEMA,
1179
+ "source_commit": self.policy["source_commit"],
1180
+ "version": self.policy["version"],
1181
+ }
1182
+
1183
+ def close(self) -> None:
1184
+ stop(self.canary)
1185
+ if self.root.exists() and not self.root.is_symlink():
1186
+ shutil.rmtree(self.root)
1187
+
1188
+
1189
+ def campaign_main(argv: list[str]) -> int:
1190
+ if os.geteuid() != 0:
1191
+ raise SystemExit("P0 native campaign must run as root")
1192
+ parser = argparse.ArgumentParser()
1193
+ parser.add_argument("--workload-user", required=True)
1194
+ parser.add_argument("--operator", required=True)
1195
+ parser.add_argument("--runtime", required=True, type=Path)
1196
+ parser.add_argument("--real-model", required=True, type=Path)
1197
+ parser.add_argument("--output", required=True, type=Path)
1198
+ args = parser.parse_args(argv)
1199
+ if (
1200
+ args.output.exists()
1201
+ or args.output.is_symlink()
1202
+ or not args.output.parent.is_dir()
1203
+ or any(path.is_symlink() or not path.is_file() for path in (args.runtime, args.real_model))
1204
+ ):
1205
+ raise SystemExit("P0 output must be new and fixtures must be regular files")
1206
+ pwd.getpwnam(args.workload_user)
1207
+ pwd.getpwnam(args.operator)
1208
+ campaign = Campaign(
1209
+ script=Path(__file__).resolve(),
1210
+ workload=args.workload_user,
1211
+ operator=args.operator,
1212
+ runtime=args.runtime,
1213
+ real_model=args.real_model,
1214
+ output=args.output,
1215
+ )
1216
+ try:
1217
+ value = campaign.run()
1218
+ args.output.write_text(
1219
+ json.dumps(value, sort_keys=True) + "\n",
1220
+ encoding="utf-8",
1221
+ )
1222
+ print(json.dumps({"output": str(args.output), "result": "PASS"}, sort_keys=True))
1223
+ return 0
1224
+ except BaseException as error:
1225
+ if not args.output.exists():
1226
+ args.output.write_text(
1227
+ json.dumps(
1228
+ {
1229
+ "error": f"{type(error).__name__}: {error}",
1230
+ "result": "FAIL",
1231
+ "schema_version": SCHEMA,
1232
+ },
1233
+ sort_keys=True,
1234
+ )
1235
+ + "\n",
1236
+ encoding="utf-8",
1237
+ )
1238
+ raise
1239
+ finally:
1240
+ campaign.close()
1241
+
1242
+
1243
+ def main() -> int:
1244
+ if len(sys.argv) >= 2 and sys.argv[1] == "fixture-evidence":
1245
+ return fixture_evidence(sys.argv[2:])
1246
+ if len(sys.argv) >= 2 and sys.argv[1] == "fixture-storm":
1247
+ return fixture_storm(sys.argv[2:])
1248
+ if len(sys.argv) >= 2 and sys.argv[1] == "fixture-exec":
1249
+ return fixture_exec(sys.argv[2:])
1250
+ return campaign_main(sys.argv[1:])
1251
+
1252
+
1253
+ if __name__ == "__main__":
1254
+ raise SystemExit(main())
scripts/verify_release.py CHANGED
@@ -50,6 +50,18 @@ def checksums(path: Path) -> dict[str, str]:
50
  return result
51
 
52
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  def main() -> int:
54
  parser = argparse.ArgumentParser()
55
  parser.add_argument("--artifact", required=True, type=Path)
@@ -84,6 +96,8 @@ def main() -> int:
84
  raise SystemExit("artifact version is inconsistent")
85
  if manifest.get("artifact") != args.artifact.name:
86
  raise SystemExit("release manifest is inconsistent")
 
 
87
  expected = {
88
  prefix + name
89
  for name in (
@@ -115,6 +129,7 @@ def main() -> int:
115
  "scripts/self_validate.py",
116
  "scripts/run_autonomous_matrix.py",
117
  "scripts/run_native_matrix.py",
 
118
  "scripts/benchmark_overhead.py",
119
  "scripts/verify_evidence.py",
120
  "scripts/package_evidence.py",
 
50
  return result
51
 
52
 
53
+ def artifact_source_commit(path: Path) -> str:
54
+ with zipfile.ZipFile(path) as archive:
55
+ try:
56
+ raw = archive.read("lumi_eggcracker/build_info.py")
57
+ except KeyError as error:
58
+ raise SystemExit("artifact source identity is missing") from error
59
+ match = re.fullmatch(b'SOURCE_COMMIT = "([0-9a-f]{40})"\r?\n', raw)
60
+ if match is None:
61
+ raise SystemExit("artifact source identity is invalid")
62
+ return match.group(1).decode("ascii")
63
+
64
+
65
  def main() -> int:
66
  parser = argparse.ArgumentParser()
67
  parser.add_argument("--artifact", required=True, type=Path)
 
96
  raise SystemExit("artifact version is inconsistent")
97
  if manifest.get("artifact") != args.artifact.name:
98
  raise SystemExit("release manifest is inconsistent")
99
+ if manifest.get("source_commit") != artifact_source_commit(args.artifact):
100
+ raise SystemExit("artifact and manifest source identities differ")
101
  expected = {
102
  prefix + name
103
  for name in (
 
129
  "scripts/self_validate.py",
130
  "scripts/run_autonomous_matrix.py",
131
  "scripts/run_native_matrix.py",
132
+ "scripts/run_p0_native.py",
133
  "scripts/benchmark_overhead.py",
134
  "scripts/verify_evidence.py",
135
  "scripts/package_evidence.py",
tests/test_installer_security.py CHANGED
@@ -62,4 +62,5 @@ class InstallerSecurityTests(unittest.TestCase):
62
  installer = INSTALLER.read_text(encoding="utf-8")
63
  self.assertIn("--expected-sha256", installer)
64
  self.assertIn("/proc/self/fd/{artifact_descriptor}", installer)
65
-
 
 
62
  installer = INSTALLER.read_text(encoding="utf-8")
63
  self.assertIn("--expected-sha256", installer)
64
  self.assertIn("/proc/self/fd/{artifact_descriptor}", installer)
65
+ self.assertIn("read_stable_regular", installer)
66
+ self.assertIn("artifact_source_commit", installer)