An EL2 monitor/hypervisor and toolchain that boots macOS 27 on the ASUS A16 (Snapdragon X2 Elite), with an Adreno Metal plug-in and IOGPU kext, and air2ir3, an AIR to Mesa ir3 shader compiler. MIT, with GPL-2.0 components listed in LICENSE and THIRD_PARTY_NOTICES.md. No Apple, Qualcomm, ASUS or Microsoft binaries are included.
67 lines
3.5 KiB
Python
Executable File
67 lines
3.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# SPDX-License-Identifier: MIT
|
|
"""Reject corrupt proof telemetry and mismatches with the independent walk."""
|
|
import copy
|
|
from pathlib import Path
|
|
import runpy
|
|
import struct
|
|
import unittest
|
|
|
|
decode=runpy.run_path(str(Path(__file__).with_name('capture-service-profile.py')))['decode_kernel_class_proof']
|
|
|
|
class ClassProofCapture(unittest.TestCase):
|
|
def setUp(self):
|
|
self.first=0x100000;self.limit=self.first+0x40000;self.allocated=self.first+0x20000
|
|
self.header=[130,128,2,0,0,2,1,1,1,2,1,self.first,512,self.first,self.limit,2,4,4,4,4]
|
|
self.bitmap=15
|
|
self.kernel=dict(canonical_root=hex(self.first),canonical_tables=4,
|
|
canonical_table_pages=[hex(self.first+n*4096) for n in range(4)],
|
|
selector_4k_pages={'2':4})
|
|
def read(self):
|
|
raw=struct.pack('<20Q',*self.header)+self.bitmap.to_bytes(4096,'little')
|
|
return decode(raw,self.kernel,130,self.first,self.limit,self.allocated)
|
|
def test_independent_walk_matches_valid_snapshot(self):
|
|
self.assertTrue(self.read()['current_snapshot_verified'])
|
|
def test_installed_bitmap_shape(self):
|
|
# A wider arena cannot truncate the proof bitmap or skip its audit.
|
|
self.limit=self.first+61440*4096;self.header[14]=self.limit
|
|
raw=struct.pack('<20Q',*self.header)+self.bitmap.to_bytes(7680,'little')
|
|
self.assertTrue(decode(raw,self.kernel,130,self.first,self.limit,self.allocated)['current_snapshot_verified'])
|
|
corrupt=bytearray(raw);corrupt[-1]=128
|
|
with self.assertRaises(ValueError):decode(corrupt,self.kernel,130,self.first,self.limit,self.allocated)
|
|
with self.assertRaises(ValueError):decode(raw[:-1],self.kernel,130,self.first,self.limit,self.allocated)
|
|
def test_invalid_snapshot_does_not_claim_current_coverage(self):
|
|
self.header[10]=0;self.header[15]=1
|
|
self.kernel['canonical_tables']=5
|
|
self.kernel['canonical_table_pages'].append(hex(self.first+0x5000))
|
|
self.assertFalse(self.read()['current_snapshot_verified'])
|
|
def test_corrupt_header_fields_rejected(self):
|
|
mutations={0:129,1:127,2:1,3:1,4:1,5:0,6:3,7:2,8:2,9:3,10:2,
|
|
11:self.first+4096,12:0,13:self.first+4096,14:self.limit+4096,
|
|
15:1,16:3,17:5,18:512,19:3}
|
|
for index,value in mutations.items():
|
|
with self.subTest(field=index):
|
|
before=self.header[index];self.header[index]=value
|
|
with self.assertRaises(ValueError):self.read()
|
|
self.header[index]=before
|
|
def test_bitmap_corruption_rejected(self):
|
|
for bits in [14,7,31,23,15|(1<<32),15|(1<<32767)]:
|
|
with self.subTest(bits=bits):
|
|
self.bitmap=bits
|
|
with self.assertRaises(ValueError):self.read()
|
|
def test_independent_coverage_mismatch_rejected(self):
|
|
original=copy.deepcopy(self.kernel)
|
|
for pages in [[hex(self.first)]*4,
|
|
[hex(self.first+n*4096) for n in (0,1,2,4)],
|
|
[hex(self.first+n*4096) for n in (0,1,2,32)],
|
|
[hex(self.first+n) for n in (0,4096,8192,12289)]]:
|
|
self.kernel=copy.deepcopy(original);self.kernel['canonical_table_pages']=pages
|
|
with self.assertRaises(ValueError):self.read()
|
|
def test_independent_leaf_summary_mismatch_rejected(self):
|
|
self.kernel['selector_4k_pages']={'3':4}
|
|
with self.assertRaises(ValueError):self.read()
|
|
self.kernel['selector_4k_pages']={'2':3}
|
|
with self.assertRaises(ValueError):self.read()
|
|
|
|
if __name__=='__main__':unittest.main()
|