Package portable Linux runtime and verify Google CPU search

This commit is contained in:
karl committed 2026-10-13 00:43:20 +02:00
1 parent e3558a0104
commit 0b56ab553c
22 files changed
+1585 -16

No files matched your search

+85 -1
View File
@@ -3,6 +3,7 @@ import argparse
import hashlib
import json
import os
import platform
import re
from pathlib import Path
import shutil
@@ -17,6 +18,87 @@ WINDOWS_CRT_FILES = (
"msvcp140_atomic_wait.dll", "msvcp140_codecvt_ids.dll", "vccorlib140.dll",
"vcruntime140.dll", "vcruntime140_1.dll", "vcruntime140_threads.dll",
)
LINUX_CPU_VARIANTS = {"x64", "sse42", "sandybridge", "ivybridge", "piledriver", "haswell",
"skylakex", "cannonlake", "cascadelake", "icelake", "cooperlake", "zen4",
"alderlake", "sapphirerapids"}
LINUX_SYSTEM_LIBRARIES = {"libc.so.6", "libm.so.6", "libdl.so.2", "libpthread.so.0",
"librt.so.1", "libstdc++.so.6", "libgcc_s.so.1", "ld-linux-x86-64.so.2"}
def linux_dispatch(backend):
"""Only normal Linux Vulkan modes use the packaged shared-module layout."""
return (sys.platform.startswith("linux") and platform.machine().lower() in {"amd64", "x86_64"}
and backend in {"auto", "vulkan"})
def elf_dynamic(path):
"""Read ELF metadata without executing the artifact or following ldd hooks."""
output = subprocess.check_output(["readelf", "--dynamic", str(path)], text=True)
values = {}
for key, value in re.findall(r"\((NEEDED|SONAME|RUNPATH|RPATH)\).*?\[([^\]]+)\]", output):
values.setdefault(key, []).append(value)
return values
def bundle_linux_libraries(build):
"""Flatten approved SONAME files beside the worker and record dependency closure.
System libc/C++ ABI remains a declared distro compatibility gate. Vulkan's
loader is optional: only the dynamically loaded GPU module may depend on it.
Preflight precedes flattening; the preceding CMake build itself is not a
transactional release replacement. Staging performs that separate swap.
"""
build = Path(build)
worker = build / "searchi-gemma-worker"
candidates = [build / "bin" / f"lib{name}.so" for name in ("ggml", "ggml-base", "llama", "mtmd")]
candidates += [build / f"libggml-cpu-{variant}.so" for variant in sorted(LINUX_CPU_VARIANTS)]
candidates.append(build / "libggml-vulkan.so")
records = []
names = set()
for link in candidates:
if not link.is_file():
raise RuntimeError(f"Required Linux runtime library is missing: {link.name}")
source = link.resolve()
if not source.is_relative_to(build.resolve()) or not source.is_file():
raise RuntimeError("Linux runtime library escapes its build directory")
metadata = elf_dynamic(source)
sonames = metadata.get("SONAME", [])
module = link.parent == build
if ((not module and len(sonames) != 1) or len(sonames) > 1
or any(not re.fullmatch(r"lib[A-Za-z0-9_-]+\.so(?:\.\d+)*", name) for name in sonames)):
raise RuntimeError("Linux runtime has invalid or missing SONAME")
# Backend discovery uses the unversioned module filename; core linkage
# uses its SONAME. Both destinations are actual files, never symlinks.
name = link.name if module else sonames[0]
if name in names:
raise RuntimeError("Duplicate Linux runtime library")
names.add(name)
destination = build / name
records.append((source, destination, metadata))
all_names = names
for path, metadata in [(worker, elf_dynamic(worker)), *[(destination, metadata) for _, destination, metadata in records]]:
if metadata.get("RPATH") or metadata.get("RUNPATH") != ["$ORIGIN"]:
raise RuntimeError(f"Linux runtime requires origin-only RUNPATH: {path.name}")
needed = set(metadata.get("NEEDED", []))
allowed = all_names | LINUX_SYSTEM_LIBRARIES
if path.name == "libggml-vulkan.so":
allowed = allowed | {"libvulkan.so.1"}
if needed - allowed:
raise RuntimeError(f"Unpackaged Linux runtime dependency for {path.name}: {sorted(needed - allowed)}")
for source, destination, _ in records:
if destination != source:
if destination.is_symlink():
destination.unlink()
shutil.copy2(source, destination)
def checksum(path):
with path.open("rb") as stream:
return hashlib.file_digest(stream, "sha256").hexdigest()
inventory = {"platform": "linux", "worker_sha256": checksum(worker),
"libraries": [{"path": path.name, "bytes": path.stat().st_size, "sha256": checksum(path)}
for _, path, _ in sorted(records)]}
temporary = build / "runtime-libraries.json.partial"
temporary.write_text(json.dumps(inventory, indent=2), encoding="utf-8")
os.replace(temporary, build / "runtime-libraries.json")
def bundle_windows_crt(build):
@@ -90,7 +172,7 @@ def main():
reverse = subprocess.run(["git", "apply", "--reverse", "--check", str(patch)], cwd=source, capture_output=True)
if reverse.returncode:
raise RuntimeError("Runtime memory patch cannot be applied or verified")
if os.name == "nt" and args.backend != "cpu":
if (os.name == "nt" and args.backend != "cpu") or linux_dispatch(args.backend):
for patch_name in ["cpu-dispatch.patch", "cpu-only-loader.patch"]:
dispatch_patch = Path(__file__).with_name(patch_name)
check = subprocess.run(["git", "apply", "--check", str(dispatch_patch)], cwd=source, capture_output=True)
@@ -125,6 +207,8 @@ def main():
temporary = directory / "runtime-libraries.json.partial"
temporary.write_text(json.dumps(inventory, indent=2), encoding="utf-8")
os.replace(temporary, directory / "runtime-libraries.json")
if linux_dispatch(args.backend):
bundle_linux_libraries(build)
print(f"Runtime build complete: {build}")
+165
View File
@@ -0,0 +1,165 @@
"""Prove Linux auto CPU fallback with the Vulkan loader physically absent.
Run as root on x86_64 Linux with util-linux unshare/mount/umount and chroot.
This tool never escalates privileges. It launches itself inside a private mount
namespace and verifies that namespace before changing mount propagation. The
sealed chroot includes approved runtime files, standard C/C++ ABI libraries and
a read-only Google model, without Vulkan loaders, ICDs, drivers or GPU devices.
This tests missing-loader fallback, not GPU execution or distro compatibility.
"""
import argparse
import hashlib
import json
import math
import os
from pathlib import Path
import platform
import shutil
import subprocess
import sys
import tempfile
ABI = ("libc.so.6", "libm.so.6", "libdl.so.2", "libpthread.so.0",
"librt.so.1", "libstdc++.so.6", "libgcc_s.so.1")
def require(condition, message):
if not condition:
raise RuntimeError(message)
def checksum(path):
with Path(path).open("rb") as stream:
return hashlib.file_digest(stream, "sha256").hexdigest()
def namespace(pid="self"):
return Path(f"/proc/{pid}/ns/mnt").stat().st_ino
def isolated_check(args, commands):
# Check the still-live outer process as well as its recorded namespace.
# A direct child invocation in the outer namespace fails before any mount.
outer = namespace(args.outer_pid)
require(outer == args.outer_namespace and namespace() != outer,
"Private mount namespace was not established; refusing mount changes")
subprocess.run([commands["mount"], "--make-rprivate", "/"], check=True)
from stage_runtime import verify_runtime
worker = args.worker.resolve()
dependencies = verify_runtime(worker, True)
manifest = json.loads(Path(__file__).with_name("model-manifest.json").read_text())
artifact = manifest["files"][0]
model = args.models.resolve() / artifact["path"]
require(model.is_file() and model.stat().st_size == artifact["bytes"]
and checksum(model) == artifact["sha256"], "Google model verification failed")
base = Path(tempfile.gettempdir()).resolve()
root = Path(tempfile.mkdtemp(prefix="searchi-loader-chroot-", dir=base)).resolve()
require(root.parent == base and root.stat().st_uid == 0,
"Invalid owned chroot directory")
mounted = []
try:
app = root / "app"
app.mkdir()
for source in [worker, *dependencies]:
destination = app / source.name
shutil.copy2(source, destination)
require(checksum(source) == checksum(destination), "Copied runtime checksum mismatch")
abi_dir = root / "lib/x86_64-linux-gnu"
abi_dir.mkdir(parents=True)
for name in ABI:
shutil.copy2(Path("/lib/x86_64-linux-gnu") / name, abi_dir / name)
(root / "lib64").mkdir()
shutil.copy2("/lib64/ld-linux-x86-64.so.2", root / "lib64/ld-linux-x86-64.so.2")
(root / "models").mkdir()
mounted_model = root / "models/model.gguf"
mounted_model.touch()
proc = root / "proc"
proc.mkdir()
subprocess.run([commands["mount"], "--bind", str(model), str(mounted_model)], check=True)
mounted.append(mounted_model)
subprocess.run([commands["mount"], "-o", "remount,bind,ro", str(mounted_model)], check=True)
subprocess.run([commands["mount"], "-t", "proc", "-o", "ro,nosuid,nodev,noexec", "proc", str(proc)], check=True)
mounted.append(proc)
require(not (root / "dev").exists() and not (root / "etc").exists(),
"Unexpected devices or driver configuration in chroot")
require({path.name for path in abi_dir.iterdir()} == set(ABI), "Unexpected system library")
require({path.name for path in app.iterdir()} == {worker.name, *(p.name for p in dependencies)},
"Unexpected runtime file")
# The worker runs with no inherited loader/ggml variables and no CPU
# override: the absence of libvulkan must cause its actual auto fallback.
environment = {"PATH": "/usr/bin:/bin", "LANG": "C.UTF-8"}
process = subprocess.Popen([commands["chroot"], str(root), "/app/searchi-gemma-worker",
"--model", "/models/model.gguf", "--threads", "1", "--device", "auto"],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, encoding="utf-8", env=environment)
try:
stdout, stderr = process.communicate(json.dumps({"op": "code_query",
"text": "retry failed requests with exponential backoff"}) + "\n", timeout=180)
except BaseException:
process.kill()
process.wait(timeout=10)
raise
require(process.returncode == 0, f"Worker failed: {stderr[-4096:]}")
lines = [json.loads(line) for line in stdout.splitlines()]
require(len(lines) == 2, "Unexpected protocol output")
hello, result = lines
require(hello.get("ready") and hello.get("device") == "cpu"
and not hello.get("vulkan_module_loaded") and result.get("ok")
and result.get("device") == "cpu", "Expected auto fallback to CPU without Vulkan loading")
vectors = result.get("vectors", [])
require(len(vectors) == 1 and len(vectors[0]) == 768
and all(isinstance(v, (float, int)) and math.isfinite(v) for v in vectors[0]),
"Invalid real Google vector")
norm = math.sqrt(sum(value * value for value in vectors[0]))
require(abs(norm - 1) < .001, "Google vector is not normalized")
evidence = {"platform": "linux", "device_requested": "auto", "forced_cpu": False,
"gpu_execution": False, "vulkan_loader_present": False,
"seal": {"system_abi": list(ABI), "proc_read_only": True, "model_read_only": True,
"private_mount_namespace_verified": True, "gpu_devices": False,
"icd_manifests": False, "environment": environment},
"worker_sha256": checksum(worker), "model_sha256": checksum(model),
"hello": hello, "dimensions": len(vectors[0]), "norm": norm,
"limitations": ["Actual GPU and driver recovery untested", "Distribution ABI compatibility untested"]}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(evidence, indent=2) + "\n", encoding="utf-8")
print(json.dumps({"auto_without_loader": "cpu", "cpu_module": hello["cpu_backend_module"],
"vulkan_loaded": False}))
finally:
failures = []
for path in reversed(mounted):
result = subprocess.run([commands["umount"], str(path)], check=False)
if result.returncode:
failures.append(str(path))
# Never recursively remove a directory containing a live bind mount.
require(not failures, f"Mount cleanup failed; preserved owned directory {root}")
require(root.parent == base and root.name.startswith("searchi-loader-chroot-"),
"Refusing cleanup outside owned temporary directory")
shutil.rmtree(root)
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--worker", type=Path, required=True)
parser.add_argument("--models", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--outer-pid", type=int, help=argparse.SUPPRESS)
parser.add_argument("--outer-namespace", type=int, help=argparse.SUPPRESS)
args = parser.parse_args()
require(sys.platform.startswith("linux") and platform.machine().lower() in {"amd64", "x86_64"},
"Run this check on x86_64 Linux")
require(os.geteuid() == 0, "Run explicitly as root; this tool does not escalate privileges")
commands = {name: shutil.which(name) for name in ("unshare", "mount", "umount", "chroot")}
require(all(commands.values()), "Install util-linux mount tools and chroot")
if args.outer_pid is not None or args.outer_namespace is not None:
require(args.outer_pid is not None and args.outer_namespace is not None,
"Incomplete namespace handoff")
isolated_check(args, commands)
else:
subprocess.run([commands["unshare"], "--mount", "--fork", sys.executable, str(Path(__file__).resolve()),
"--worker", str(args.worker.resolve()), "--models", str(args.models.resolve()),
"--output", str(args.output.resolve()), "--outer-pid", str(os.getpid()),
"--outer-namespace", str(namespace())], check=True)
if __name__ == "__main__":
main()
+106
View File
@@ -0,0 +1,106 @@
"""Exercise a real Linux distribution worker on CPU, outside its build directory.
This checks genuine Google inference and origin-relative runtime packaging.
It does not certify GPU operation, older processors or a Linux desktop.
"""
import argparse
import hashlib
import json
import math
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
import time
def sha256(path):
with path.open("rb") as stream:
return hashlib.file_digest(stream, "sha256").hexdigest()
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--worker", type=Path, required=True)
parser.add_argument("--models", type=Path, required=True)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--baseline", action="store_true")
args = parser.parse_args()
if os.name != "posix" or not Path("/proc/self/exe").exists():
parser.error("Run this check natively on Linux")
# Reuse exactly the staging verifier: hashes and bounded inventory names
# must agree with what enters a distribution.
from stage_runtime import verify_runtime
dependencies = verify_runtime(args.worker.resolve(), True)
manifest = json.loads(Path(__file__).with_name("model-manifest.json").read_text())
model = args.models.resolve() / manifest["files"][0]["path"]
if model.stat().st_size != manifest["files"][0]["bytes"] or sha256(model) != manifest["files"][0]["sha256"]:
raise RuntimeError("Google model checksum mismatch")
with tempfile.TemporaryDirectory(prefix="searchi-linux-smoke-") as temporary:
target = Path(temporary)
copied = []
for source in [args.worker.resolve(), *dependencies]:
# Only exact approved CPU module names are omitted. Core libraries
# and GPU support remain present in the baseline extraction.
if args.baseline and source.name.startswith("libggml-cpu-") and source.name != "libggml-cpu-x64.so":
continue
destination = target / source.name
shutil.copy2(source, destination)
if sha256(destination) != sha256(source):
raise RuntimeError("Extracted runtime checksum mismatch")
copied.append(source.name)
worker = target / args.worker.name
dynamic = subprocess.check_output(["readelf", "-d", str(worker)], text=True)
if "libvulkan" in dynamic or "libggml-vulkan" in dynamic:
raise RuntimeError("Worker requires Vulkan at process startup; CPU fallback cannot work without the loader")
if "$ORIGIN" not in dynamic:
raise RuntimeError("Worker lacks origin-relative runtime lookup")
environment = dict(os.environ, SEARCHI_FORCE_CPU="1", GGML_DISABLE_VULKAN="1")
environment.pop("LD_LIBRARY_PATH", None)
environment.pop("GGML_BACKEND_PATH", None)
started = time.perf_counter()
process = subprocess.Popen([str(worker), "--model", str(model), "--threads", "1", "--device", "cpu"],
cwd=target, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True, encoding="utf-8", env=environment)
try:
stdout, stderr = process.communicate(json.dumps({"op": "code_query", "text": "retry failed requests with exponential backoff"}) + "\n", timeout=180)
except BaseException:
process.kill()
process.wait(timeout=10)
raise
elapsed_ms = (time.perf_counter() - started) * 1000
if process.returncode:
raise RuntimeError(f"Worker failed ({process.returncode}): {stderr[-4096:]}")
lines = [json.loads(line) for line in stdout.splitlines()]
if len(lines) != 2:
raise RuntimeError("Unexpected worker protocol output")
hello, result = lines
if not hello.get("ready") or hello.get("device") != "cpu" or not result.get("ok") or result.get("device") != "cpu":
raise RuntimeError("Expected genuine ready CPU inference")
if hello.get("vulkan_module_loaded"):
raise RuntimeError("CPU check loaded a Vulkan provider")
vectors = result.get("vectors")
vector = vectors[0] if isinstance(vectors, list) and len(vectors) == 1 else None
if not isinstance(vector, list) or len(vector) != 768 or not all(isinstance(value, (int, float)) and math.isfinite(value) for value in vector):
raise RuntimeError("Invalid Google embedding vector")
norm = math.sqrt(sum(value * value for value in vector))
if abs(norm - 1) > 0.001:
raise RuntimeError("Google vector is not normalized")
module = hello.get("cpu_backend_module", "")
if args.baseline and module != "libggml-cpu-x64.so":
raise RuntimeError(f"Baseline extraction selected unexpected CPU module: {module}")
evidence = {"platform": "linux", "cpu_only": True, "baseline_only_extraction": args.baseline,
"worker_sha256": sha256(args.worker), "model_sha256": sha256(model),
"files": sorted(copied), "hello": hello, "dimensions": len(vector), "norm": norm,
"startup_query_exit_ms": elapsed_ms,
"timing_scope": "single diagnostic smoke sample; not a performance benchmark",
"worker_dynamic_section": dynamic,
"limitations": ["GPU untested", "older physical CPUs untested", "desktop and installer untested", "system-loader absence not physically exercised"]}
args.output.parent.mkdir(parents=True, exist_ok=True)
args.output.write_text(json.dumps(evidence, indent=2) + "\n", encoding="utf-8")
print(json.dumps({"ready": True, "cpu_module": module, "dimensions": 768, "baseline": args.baseline}))
if __name__ == "__main__":
main()
+21 -6
View File
@@ -15,6 +15,11 @@ ROOT = Path(__file__).resolve().parents[2]
CRT_LIBRARIES = {"concrt140.dll", "msvcp140.dll", "msvcp140_1.dll", "msvcp140_2.dll", "msvcp140_atomic_wait.dll", "msvcp140_codecvt_ids.dll", "vccorlib140.dll", "vcruntime140.dll", "vcruntime140_1.dll", "vcruntime140_threads.dll"}
def library_name(name):
return isinstance(name, str) and bool(re.fullmatch(
r"(?:[A-Za-z0-9_-]+\.dll|lib[A-Za-z0-9_-]+\.so(?:\.\d+)*)", name))
def _is_link(path):
"""Reject Windows reparse points, including junctions, on Python 3.11+."""
path = Path(path)
@@ -208,7 +213,7 @@ def _previous_owned(destination):
raise RuntimeError("Invalid previous runtime inventory")
for record in records:
name = record.get("path") if isinstance(record, dict) else None
if not isinstance(name, str) or not re.fullmatch(r"[A-Za-z0-9_-]+\.dll", name):
if not library_name(name):
raise RuntimeError("Invalid previous runtime library path")
names.add(name)
return names
@@ -345,7 +350,7 @@ def verify_runtime(source, required=False):
if not isinstance(record, dict):
raise RuntimeError("Invalid runtime library metadata")
name = record.get("path", "")
if not isinstance(name, str) or not re.fullmatch(r"[A-Za-z0-9_-]+\.dll", name) or name.lower() in names:
if not library_name(name) or name.lower() in names:
raise RuntimeError("Invalid or duplicate runtime library path")
names.add(name.lower())
artifact = source.parent / name
@@ -361,8 +366,17 @@ def verify_runtime(source, required=False):
if hashlib.file_digest(stream, "sha256").hexdigest() != checksum:
raise RuntimeError(f"Runtime library checksum mismatch: {name}")
paths.append(artifact)
if required and not ({"ggml-cpu-x64.dll", "ggml-vulkan.dll", "vulkan-1.dll", "ggml.dll", "ggml-base.dll", "llama.dll", "mtmd.dll"} | CRT_LIBRARIES).issubset(names):
raise RuntimeError("Runtime inventory lacks required CPU/GPU libraries")
if required:
if (source.suffix == ".exe") == (manifest.get("platform") == "linux"):
raise RuntimeError("Runtime inventory platform does not match worker")
if manifest.get("platform") == "linux":
core = {"ggml", "ggml-base", "llama", "mtmd"}
present = {name for name in core if any(re.fullmatch(rf"lib{re.escape(name)}\.so(?:\.\d+)*", file) for file in names)}
complete = present == core and {"libggml-cpu-x64.so", "libggml-vulkan.so"}.issubset(names)
else:
complete = ({"ggml-cpu-x64.dll", "ggml-vulkan.dll", "vulkan-1.dll", "ggml.dll", "ggml-base.dll", "llama.dll", "mtmd.dll"} | CRT_LIBRARIES).issubset(names)
if not complete:
raise RuntimeError("Runtime inventory lacks required CPU/GPU libraries")
return [inventory, *paths]
@@ -401,7 +415,8 @@ def main():
license_path = ROOT / ".searchi/references/llama.cpp/LICENSE"
if not license_path.is_file():
raise RuntimeError("Native worker license is missing")
dependencies = verify_runtime(source, os.name == "nt" and args.backend in {"auto", "vulkan"})
required_inventory = (os.name == "nt" or os.sys.platform.startswith("linux")) and args.backend in {"auto", "vulkan"}
dependencies = verify_runtime(source, required_inventory)
crt_notice = source.parent / "MSVC-REDISTRIBUTION.txt"
if os.name == "nt" and args.backend != "cpu":
if not crt_notice.is_file():
@@ -425,7 +440,7 @@ def main():
sources.extend((path, f"embeddinggemma2/{path.name}") for path in artifacts)
def validate(candidate):
verify_runtime(candidate / source.name, os.name == "nt" and args.backend in {"auto", "vulkan"})
verify_runtime(candidate / source.name, required_inventory)
if model_manifest:
for artifact, spec in zip(artifacts, model_manifest["files"], strict=True):
if _record(candidate / "embeddinggemma2" / artifact.name) != (spec["bytes"], spec["sha256"]):
@@ -1,11 +1,87 @@
"""Redistributable preparation tests; no native builds or GPU execution."""
from pathlib import Path
import json
import tempfile
import unittest
from unittest.mock import patch
import build_runtime
from build_runtime import bundle_windows_crt, WINDOWS_CRT_FILES
class LinuxRuntimeTests(unittest.TestCase):
def test_only_normal_linux_vulkan_modes_use_shared_dispatch(self):
with patch.object(build_runtime.sys, "platform", "linux"), patch.object(build_runtime.platform, "machine", return_value="x86_64"):
for backend in ["auto", "vulkan"]:
self.assertTrue(build_runtime.linux_dispatch(backend))
for backend in ["cpu", "cuda", "metal"]:
self.assertFalse(build_runtime.linux_dispatch(backend))
with patch.object(build_runtime.sys, "platform", "darwin"):
self.assertFalse(build_runtime.linux_dispatch("auto"))
with patch.object(build_runtime.sys, "platform", "linux"), patch.object(build_runtime.platform, "machine", return_value="aarch64"):
self.assertFalse(build_runtime.linux_dispatch("auto"))
self.assertFalse(build_runtime.linux_dispatch("vulkan"))
def test_readelf_parses_needed_soname_and_runpath_without_executing_worker(self):
output = " 0x1 (NEEDED) Shared library: [libggml.so.0]\n 0xe (SONAME) Library soname: [libggml-cpu-x64.so]\n 0x1d (RUNPATH) Library runpath: [$ORIGIN]\n"
with patch.object(build_runtime.subprocess, "check_output", return_value=output) as command:
result = build_runtime.elf_dynamic(Path("worker"))
self.assertEqual(result, {"NEEDED": ["libggml.so.0"], "SONAME": ["libggml-cpu-x64.so"], "RUNPATH": ["$ORIGIN"]})
command.assert_called_once_with(["readelf", "--dynamic", "worker"], text=True)
def fixture(self, root):
root = Path(root)
(root / "bin").mkdir()
(root / "searchi-gemma-worker").write_bytes(b"worker")
for name in ["ggml", "ggml-base", "llama", "mtmd"]:
(root / "bin" / f"lib{name}.so").write_bytes(name.encode())
for variant in build_runtime.LINUX_CPU_VARIANTS:
(root / f"libggml-cpu-{variant}.so").write_bytes(variant.encode())
(root / "libggml-vulkan.so").write_bytes(b"vulkan")
return root
def metadata(self, path):
result = {"RUNPATH": ["$ORIGIN"], "NEEDED": ["libstdc++.so.6", "libc.so.6"]}
if path.parent.name == "bin":
result["SONAME"] = [path.name + ".0"]
if path.name == "libggml-vulkan.so":
result["NEEDED"].append("libvulkan.so.1")
return result
def test_flattened_core_and_bounded_modules_have_hashed_inventory(self):
with tempfile.TemporaryDirectory() as directory:
root = self.fixture(directory)
with patch.object(build_runtime, "elf_dynamic", side_effect=self.metadata):
build_runtime.bundle_linux_libraries(root)
manifest = json.loads((root / "runtime-libraries.json").read_text())
self.assertEqual(manifest["platform"], "linux")
self.assertEqual(len(manifest["libraries"]), 5 + len(build_runtime.LINUX_CPU_VARIANTS))
self.assertTrue((root / "libllama.so.0").is_file())
self.assertTrue(all(not (root / item["path"]).is_symlink() for item in manifest["libraries"]))
self.assertTrue(all(len(item["sha256"]) == 64 for item in manifest["libraries"]))
def test_startup_gpu_dependency_and_build_tree_rpath_are_rejected(self):
for problem in ["gpu", "rpath", "missing"]:
with self.subTest(problem=problem), tempfile.TemporaryDirectory() as directory:
root = self.fixture(directory)
previous = root / "libllama.so.0"
previous.write_bytes(b"previous flattened core")
def metadata(path):
result = self.metadata(path)
if path.name == "searchi-gemma-worker":
if problem == "gpu":
result["NEEDED"].append("libvulkan.so.1")
elif problem == "rpath":
result["RUNPATH"] = ["/private/build"]
else:
result["NEEDED"].append("libunpackaged.so.9")
return result
with patch.object(build_runtime, "elf_dynamic", side_effect=metadata), self.assertRaises(RuntimeError):
build_runtime.bundle_linux_libraries(root)
self.assertFalse((root / "runtime-libraries.json").exists())
self.assertEqual(previous.read_bytes(), b"previous flattened core")
class CrtTests(unittest.TestCase):
def fixture(self, directory):
root = Path(directory)
@@ -0,0 +1,28 @@
"""Namespace guards must reject unsafe handoffs before any mount operation."""
import argparse
import unittest
from unittest.mock import patch
import linux_loader_smoke
class NamespaceGuardTests(unittest.TestCase):
def test_same_namespace_refuses_mount_before_runtime_access(self):
args = argparse.Namespace(outer_pid=123, outer_namespace=42)
with patch.object(linux_loader_smoke, "namespace", return_value=42), \
patch.object(linux_loader_smoke.subprocess, "run") as run:
with self.assertRaisesRegex(RuntimeError, "Private mount namespace"):
linux_loader_smoke.isolated_check(args, {"mount": "mount"})
run.assert_not_called()
def test_changed_outer_namespace_refuses_mount(self):
args = argparse.Namespace(outer_pid=123, outer_namespace=42)
with patch.object(linux_loader_smoke, "namespace", return_value=43), \
patch.object(linux_loader_smoke.subprocess, "run") as run:
with self.assertRaisesRegex(RuntimeError, "Private mount namespace"):
linux_loader_smoke.isolated_check(args, {"mount": "mount"})
run.assert_not_called()
if __name__ == "__main__":
unittest.main()
@@ -12,6 +12,44 @@ import stage_runtime
class StagingTests(unittest.TestCase):
def test_linux_inventory_stages_core_and_modules_and_removes_previous_owned_library(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
runtime = root / "build"
runtime.mkdir()
worker = runtime / "searchi-gemma-worker"
worker.write_bytes(b"ELF fixture for integrity, not executable inference")
names = ["libggml.so.0", "libggml-base.so.0", "libllama.so.0", "libmtmd.so.0",
"libggml-cpu-x64.so", "libggml-vulkan.so"]
records = []
for name in names:
path = runtime / name
path.write_bytes(name.encode())
records.append({"path": name, "bytes": path.stat().st_size,
"sha256": hashlib.sha256(path.read_bytes()).hexdigest()})
inventory = runtime / "runtime-libraries.json"
inventory.write_text(json.dumps({"platform": "linux", "worker_sha256": hashlib.sha256(worker.read_bytes()).hexdigest(), "libraries": records}))
dependencies = stage_runtime.verify_runtime(worker, True)
destination = root / "resources"
destination.mkdir()
(destination / "libggml-cpu-old.so").write_bytes(b"old owned backend")
(destination / "runtime-libraries.json").write_text(json.dumps({"libraries": [{"path": "libggml-cpu-old.so"}]}))
(destination / "note.txt").write_bytes(b"unrelated")
stage_runtime.stage_resources(destination, [(worker, worker.name), *[(path, path.name) for path in dependencies]],
lambda candidate: stage_runtime.verify_runtime(candidate / worker.name, True))
self.assertFalse((destination / "libggml-cpu-old.so").exists())
self.assertEqual((destination / "note.txt").read_bytes(), b"unrelated")
self.assertEqual(len(stage_runtime.verify_runtime(destination / worker.name, True)), 7)
(destination / "libggml-vulkan.so").write_bytes(b"corrupt")
with self.assertRaises(RuntimeError):
stage_runtime.verify_runtime(destination / worker.name, True)
def test_runtime_library_names_reject_paths_and_unbounded_suffixes(self):
for name in ["../libggml.so", "libggml.so.x", "libggml.so/1", "libggml.so..1", "ggml.dylib"]:
with self.subTest(name=name):
self.assertFalse(stage_runtime.library_name(name))
self.assertTrue(stage_runtime.library_name("libggml-base.so.0.13.0"))
def resources(self, directory):
root = Path(directory)
destination = root / "src-tauri/resources"