1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
#!/usr/bin/env python3
"""Extract SYS_DRV from historical psp_13_0_0_sos.bin blobs and compare with the running one.
Pass 143 recorded the anti-rollback question as blocked because the corpus held no older
build of this component for THIS ASIC. That was too quick: `psp_13_0_0_sos.bin` is the exact
file this part loads, and historical versions are public in linux-firmware.
This parses each blob with the driver's own header structs -- not a hand-rolled format guess
-- enumerates its components, and reports the SYS_DRV length, hash and version alongside the
running one. Only if a fetched build is genuinely a DIFFERENT build of the same component for
the same ASIC does a rollback attempt mean anything.
"""
import ctypes, glob, hashlib, sys
sys.path.insert(0, '/root/psp/hw')
from tinygrad import Device
import tinygrad.runtime.autogen.am.am as am
adev = Device["AMD"].iface.dev_impl
live = bytes(adev.fw.sos_fw[am.PSP_FW_TYPE_PSP_SYS_DRV])
print('LIVE SYS_DRV len=%d sha=%s' % (len(live), hashlib.sha256(live).hexdigest()[:24]),
flush=True)
names = {getattr(am, n): n.replace('PSP_FW_TYPE_PSP_', '')
for n in dir(am) if n.startswith('PSP_FW_TYPE_PSP_')}
hdrcls = None
for cand in ('struct_psp_firmware_header_v2_0', 'struct_psp_firmware_header_v1_0'):
if hasattr(am, cand): hdrcls = getattr(am, cand); break
print('header struct: %s' % (hdrcls.__name__ if hdrcls else 'NONE FOUND'), flush=True)
def parse(path):
blob = open(path, 'rb').read()
hdr = hdrcls.from_buffer_copy(blob)
ch = hdr.header
print(' %s size=%d hdr_ver=%d.%d ucode_ver=%#x' %
(path.split('/')[-1], ch.size_bytes, ch.header_version_major,
ch.header_version_minor, ch.ucode_version), flush=True)
fw_bin = hdr.psp_fw_bin
cnt = hdr.psp_aux_fw_bin_index if ch.header_version_minor == 1 else hdr.psp_fw_bin_count
for i in range(cnt):
d = am.struct_psp_fw_bin_desc.from_address(
ctypes.addressof(fw_bin) + i * ctypes.sizeof(am.struct_psp_fw_bin_desc))
start = d.offset_bytes + ch.ucode_array_offset_bytes
comp = blob[start:start + d.size_bytes]
tag = names.get(d.fw_type, hex(d.fw_type))
mark = ''
if d.fw_type == am.PSP_FW_TYPE_PSP_SYS_DRV:
mark = ' <-- SYS_DRV %s' % ('IDENTICAL to running' if comp == live
else 'DIFFERENT from running')
print(' %-14s ver=%#-10x len=%-8d sha=%s%s'
% (tag, d.fw_version, len(comp), hashlib.sha256(comp).hexdigest()[:16], mark),
flush=True)
for p in sorted(glob.glob('/root/psp/rollback/sos_*.bin')):
try: parse(p)
except Exception as e: print(' %s PARSE ERROR %s %s' % (p, type(e).__name__, str(e)[:80]))
|