<feed xmlns='http://www.w3.org/2005/Atom'>
<title>amd-psp-re.git/mes/mec_audit.py, branch main</title>
<subtitle>AMD PSP reverse engineering, emulator and vulnerability research</subtitle>
<id>https://git.sl0p.foo/amd-psp-re.git/atom/mes/mec_audit.py?h=main</id>
<link rel='self' href='https://git.sl0p.foo/amd-psp-re.git/atom/mes/mec_audit.py?h=main'/>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/amd-psp-re.git/'/>
<updated>2026-09-28T14:25:42Z</updated>
<entry>
<title>MEC/PM4 round 4: correct the dispatch table, refute the length-bound guess</title>
<updated>2026-09-28T14:25:42Z</updated>
<author>
<name>user</name>
<email>user@clank</email>
</author>
<published>2026-09-28T14:25:42Z</published>
<link rel='alternate' type='text/html' href='https://git.sl0p.foo/amd-psp-re.git/commit/?id=3b017f81e10b7cccce75c941ce2b9c9240afb879'/>
<id>urn:sha1:3b017f81e10b7cccce75c941ce2b9c9240afb879</id>
<content type='text'>
Acting on the synthesis, which put PM4 at the top because it is the only
user-submittable surface left unaudited.

Round 1's table base was 0x100 low -- the same nested-$PS1 error that shifted
every DMCUB address in this tree. At the corrected base 0x415d8 all five of
Round 1's anchor opcodes verify, and 5 of 7 populated slots carry published
PACKET3_* names (MAP_QUEUES, UNMAP_QUEUES, QUERY_STATUS, RUN_LIST,
MAP_PROCESS_VM). At the old base, zero did, which is what makes the naming a
validation rather than a decoration.

That table covers queue management only. Two scans found no second dispatch
structure -- no further (handler, flags) pairs and no plain pointer table that
opcode-indexes onto the enum -- so the remaining packets are dispatched by
compare chains, matching Round 2's reading.

Round 1's suspected per-packet length bound is refuted: MAP_QUEUES carries 2241
where UNMAP/QUERY/RUN_LIST carry 2 and MAP_PROCESS_VM carries 1. Those are not
dword counts for those packets, so the low half is a flags field and the parser's
length validation lives in code.

New tooling (mes/mec_audit.py: table/bounds/taint) taints from the packet data
port 0x6F8(tp) with dataflow that respects both calls and basic blocks. The
block rule was added after the pass produced a striking false lead: a raw packet
dword shifted left 36 into MMIO-aperture bits and used as a store address, which
would have been a host-controlled register write. An unconditional j sits just
before that block, so the base comes from elsewhere; block-awareness removed it
and 16 other sinks. Of the 75 survivors, 27 assemble a 64-bit GPU VA from two
packet dwords and are VM-confined as proven for SDMA.

Still no finding.
</content>
</entry>
</feed>
