Pin model runtime source imports before ambient hooks

This commit is contained in:
firestar5683
2026-10-23 17:38:06 -05:00
parent 0022fde1cb
commit 12601d1fac
7 changed files with 75 additions and 4 deletions
@@ -1,6 +1,7 @@
"""Select the integrity-pinned driving and monitoring runtime before imports."""
import hashlib
import importlib
import importlib.abc
import importlib.machinery
import importlib.util
import json
@@ -90,6 +91,34 @@ def _namespace(name, directory):
return importlib.util.module_from_spec(spec)
class _PinnedSourceImports(importlib.abc.MetaPathFinder):
"""Resolve only verified source files, before ambient editable/import hooks."""
def __init__(self, root):
self.roots = {'tinygrad': root / 'tinygrad', 'examples': root / 'examples',
'tinygrad_repo': root, 'extra': root / 'extra'}
def find_spec(self, fullname, path=None, target=None):
family, *parts = fullname.split('.')
if family not in self.roots:
return None
leaf = self.roots[family].joinpath(*parts)
source = leaf / '__init__.py' if (leaf / '__init__.py').is_file() else leaf.with_suffix('.py')
if source.is_file():
_plain_path(source)
return importlib.util.spec_from_file_location(fullname, source)
if leaf.is_dir():
_plain_path(leaf)
return _namespace(fullname, leaf).__spec__
raise ModuleNotFoundError('Module is outside selected runtime source: ' + fullname, name=fullname)
def _pin_source_imports(root):
finder = _PinnedSourceImports(root)
sys.meta_path.insert(0, finder)
return finder
def _check_source_package(name, expected):
spec = importlib.util.find_spec(name)
if (spec is None or not isinstance(spec.loader, importlib.machinery.SourceFileLoader) or
@@ -153,6 +182,7 @@ def activate(bundle, manifest_sha256, compiler_revision, role, cache_root):
_private_cache(cache)
_private_cache(cache / 'xdg')
old_path, old_bytecode, old_cache_prefix = sys.path[:], sys.dont_write_bytecode, sys.pycache_prefix
old_meta_path = sys.meta_path[:]
old_env = {key: os.environ.get(key) for key in _ENV_KEYS}
try:
sys.path[:0] = [str(bundle), str(tg_root)]
@@ -164,11 +194,13 @@ def activate(bundle, manifest_sha256, compiler_revision, role, cache_root):
# Fixed parent paths prevent namespace merging with the global runtime tree.
sys.modules['tinygrad_repo'] = _namespace('tinygrad_repo', tg_root)
sys.modules['extra'] = _namespace('extra', tg_root / 'extra')
_pin_source_imports(tg_root)
importlib.invalidate_caches()
_check_source_package('tinygrad', tg_root / 'tinygrad/__init__.py')
_check_source_package('examples', tg_root / 'examples/__init__.py')
except BaseException:
sys.path[:] = old_path
sys.meta_path[:] = old_meta_path
sys.dont_write_bytecode = old_bytecode
sys.pycache_prefix = old_cache_prefix
for name in ('tinygrad_repo', 'extra'):
@@ -1 +1 @@
{"compiler_revision":"9d0446a4ba8a532c8b674fb6ad795af015cd9dcf","files":{"bootstrap.py":"dcb4a3469f4e3cf93b7f2384a47e72a5559ed859d3a94c6f1b78ba72d5efa86c","bounded_wait.c":"a9e1a82e50ebefd983b3dbc6f784adc465cbd06848debed11dfff80cc8a832fe","capture.py":"834cf5d83725729f30aec68a7ba5ca4897701dd4aa34147f0b49d8b0a9b9e81a","libbounded_wait.so":"24ed559861c8636c1026cad9a244854bb2236b5ee8b91bf21c5efbf688fa4a69","libusb_guards.so":"66a3dfe48ac17899862ab80160cf6dac2c9b9707234527ba0d808f3b68404114","qcom.py":"5f35de06bae649342953bfef48c54267f0c7971756537b8758e1d0d2ec6fa7b0","usb.py":"a2e84aa6d6be4cd7b8db7bf9dae85f67a6008de5c6e93ecb288fefede2b46e23","usb_guards.c":"8b3c207de74f92b74980da35428cff6f4a198ce97f9f8b6e64aded74e0110316"},"native_abi":"linux-aarch64-64bit","runtime_manifest_sha256":"20ca9e77010c1ab788f2adb824103db3d595b0da8c4069d6e32b1266f7977b1f"}
{"compiler_revision":"9d0446a4ba8a532c8b674fb6ad795af015cd9dcf","files":{"bootstrap.py":"2efd3aaffb98d30e316fb950dac77b16f0866dfeed1c9767b97dad915e4d0c63","bounded_wait.c":"a9e1a82e50ebefd983b3dbc6f784adc465cbd06848debed11dfff80cc8a832fe","capture.py":"834cf5d83725729f30aec68a7ba5ca4897701dd4aa34147f0b49d8b0a9b9e81a","libbounded_wait.so":"24ed559861c8636c1026cad9a244854bb2236b5ee8b91bf21c5efbf688fa4a69","libusb_guards.so":"66a3dfe48ac17899862ab80160cf6dac2c9b9707234527ba0d808f3b68404114","qcom.py":"5f35de06bae649342953bfef48c54267f0c7971756537b8758e1d0d2ec6fa7b0","usb.py":"a2e84aa6d6be4cd7b8db7bf9dae85f67a6008de5c6e93ecb288fefede2b46e23","usb_guards.c":"8b3c207de74f92b74980da35428cff6f4a198ce97f9f8b6e64aded74e0110316"},"native_abi":"linux-aarch64-64bit","runtime_manifest_sha256":"20ca9e77010c1ab788f2adb824103db3d595b0da8c4069d6e32b1266f7977b1f"}
@@ -14,7 +14,7 @@ from typing import TYPE_CHECKING, Protocol, cast
from openpilot.starpilot.models.runtime_selection import NATIVE_REVISION
from openpilot.starpilot.models.runtime_bridge.bootstrap import (
IMPORT_FAMILIES, _check_source_package, _namespace, _private_cache,
IMPORT_FAMILIES, _check_source_package, _namespace, _private_cache, _pin_source_imports,
)
if TYPE_CHECKING:
@@ -199,6 +199,7 @@ def prepare(role, plan):
os.environ.update(CACHEDB=str(cache / 'tinygrad.db'), XDG_CACHE_HOME=str(cache / 'xdg'), PYTHONDONTWRITEBYTECODE='1')
sys.modules['tinygrad_repo'] = _namespace('tinygrad_repo', tg_root)
sys.modules['extra'] = _namespace('extra', tg_root / 'extra')
_pin_source_imports(tg_root)
importlib.invalidate_caches()
_check_source_package('tinygrad', tg_root / 'tinygrad/__init__.py')
_check_source_package('examples', tg_root / 'examples/__init__.py')
@@ -15,7 +15,7 @@ _GUARD_HASHES = {
'libbounded_wait.so': '24ed559861c8636c1026cad9a244854bb2236b5ee8b91bf21c5efbf688fa4a69',
'libusb_guards.so': '66a3dfe48ac17899862ab80160cf6dac2c9b9707234527ba0d808f3b68404114',
}
_POLICY_SHA256 = 'c7eae9e0fab99e8c5fa56854b5a1e1ca8c36c81ef73668dd18ede27de61e3f4b'
_POLICY_SHA256 = 'ff9a762b130207dcf9919714bccd7aabc6d3f6e9d707e0b3a0dbd7fce5858aed'
_selection = None
_protection = None
_plan = None
@@ -31,6 +31,7 @@ class ProcessCustody(unittest.TestCase):
saved_modules = sys.modules.copy()
saved_env = dict(os.environ)
saved_path = sys.path[:]
saved_meta_path = sys.meta_path[:]
saved_importers = sys.path_importer_cache.copy()
saved_bytecode = sys.dont_write_bytecode
saved_prefix = sys.pycache_prefix
@@ -41,6 +42,7 @@ class ProcessCustody(unittest.TestCase):
os.environ.clear()
os.environ.update(saved_env)
sys.path[:] = saved_path
sys.meta_path[:] = saved_meta_path
sys.dont_write_bytecode = saved_bytecode
sys.pycache_prefix = saved_prefix
importlib.invalidate_caches()
@@ -1,5 +1,7 @@
"""Integrity and import isolation of the production role bootstrap."""
import importlib
import importlib.abc
import importlib.util
import os
import sys
import types
@@ -148,3 +150,37 @@ class BootstrapTests(BootstrapFixture):
if __name__ == '__main__':
unittest.main()
class SourceHookTests(BootstrapFixture):
def test_selected_source_wins_over_ambient_meta_path_hook(self):
outside = self.base / 'ambient'
(outside / 'tinygrad').mkdir(parents=True)
(outside / 'tinygrad/__init__.py').write_text("raise AssertionError('ambient source executed')")
class AmbientHook(importlib.abc.MetaPathFinder):
def find_spec(hook, fullname, path=None, target=None):
if fullname == 'tinygrad':
return importlib.util.spec_from_file_location(fullname, outside / 'tinygrad/__init__.py')
return None
sys.meta_path.insert(0, AmbientHook())
self.activate()
selected = importlib.import_module('tinygrad')
self.assertEqual(selected.IDENTITY, 'selected legacy')
self.assertEqual(selected.__file__, str(self.bundle / 'tinygrad_repo/tinygrad/__init__.py'))
def test_selected_children_cannot_fall_back_to_ambient_hook(self):
outside = self.base / 'unowned.py'
outside.write_text("raise AssertionError('unowned child executed')")
class AmbientHook(importlib.abc.MetaPathFinder):
def find_spec(hook, fullname, path=None, target=None):
if fullname == 'tinygrad.unowned':
return importlib.util.spec_from_file_location(fullname, outside)
return None
sys.meta_path.insert(0, AmbientHook())
self.activate(role='monitoring')
with self.assertRaises(ModuleNotFoundError):
importlib.import_module('tinygrad.unowned')
+1 -1
View File
@@ -1 +1 @@
{"protected_inventory_sha256": "f29a00c7be8a21d34adb6a9262fe9786de0f9648a9fa30e91d880b036c77035d", "schema_version": 1}
{"protected_inventory_sha256": "270b5ff419c82d41512039c2b6188e14cb3a3a8115b334effb74d2090ef54cb5", "schema_version": 1}