Files
verstack/scripts/enable-arm64-builder.py

52 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""Validate Debian's ARM64 binfmt definition; install only with --install.
Run in the existing vm-builder container with the host binfmt filesystem mounted
at /host-binfmt. Keep the registering process alive for readback and rollback.
Never pass decoded binary NUL bytes to the kernel's registration text parser.
"""
import argparse
import codecs
from pathlib import Path
import subprocess
def registration(definition, native_header):
fields=dict(line.split(' ',1) for line in definition.splitlines() if ' ' in line)
magic=codecs.decode(fields['magic'],'unicode_escape').encode('latin1')
mask=codecs.decode(fields['mask'],'unicode_escape').encode('latin1')
if len(magic)!=20 or len(mask)!=20 or magic[18:20]!=b'\xb7\x00' or mask[18:20]!=b'\xff\xff':
raise ValueError('Definition must explicitly match the complete AArch64 ELF machine field')
def matches(header):return all((a&m)==(b&m) for a,b,m in zip(header,magic,mask))
if len(native_header)<20 or matches(native_header):raise ValueError('Definition matches the native interpreter host')
for machine,elf_class in ((62,2),(3,1),(40,1)):
other=bytearray(magic);other[4]=elf_class;other[18:20]=machine.to_bytes(2,'little')
if matches(other):raise ValueError('Definition matches another architecture')
value=f":verstack_arm64:M:0:{fields['magic']}:{fields['mask']}:{fields['interpreter']}:PF"
if '\0' in value or len(value.split(':'))!=8:raise ValueError('Invalid registration encoding')
return value,magic,mask
def main():
parser=argparse.ArgumentParser();parser.add_argument('--install',action='store_true')
args=parser.parse_args()
definition=Path('/usr/share/binfmts/qemu-aarch64').read_text()
value,magic,mask=registration(definition,Path('/bin/true').read_bytes()[:20])
print('Validated full ARM64 signature; x86-64, x86 and ARM32 excluded.',flush=True)
if not args.install:return
root=Path('/host-binfmt');entry=root/'verstack_arm64'
if entry.exists():raise SystemExit('Existing registration retained; inspect it before replacing.')
try:
(root/'register').write_text(value)
actual=entry.read_text()
if f'magic {magic.hex()}' not in actual or f'mask {mask.hex()}' not in actual:
raise RuntimeError('Kernel readback differs from validated signature')
subprocess.run(['/bin/true'],check=True)
except BaseException:
if entry.exists():entry.write_text('-1')
raise
print(actual,flush=True)
if __name__=='__main__':main()