aboutsummaryrefslogtreecommitdiffstats

FINDING: the PSP ring base is accepted misaligned, then wedges on first submit

Evidence class: [HW] — Navi 31 / RX 7900 XTX, sOS/SYS_DRV 0.49.0.54. Status: missing check CONFIRMED. Eighth DoS trigger. No memory corruption.

The ring-creation surface

The ring is created by writing its base (C2PMSG_69/70), its size (_71) and a create command to _64, whose low 16 bits are the PSP's own status — so the firmware reports acceptance directly and nothing has to be inferred. hw/ring_create_fuzz.py, one case per fresh boot:

case status outcome
control: correct base and size 0x0 accepted, commands execute
size 0 0x4 rejected
size 1 0x4 rejected
size 0xFFFFFFFF 0x4 rejected
size 0x80000000 0x5 rejected
base inside the TMR 0xa rejected — explicitly range-checked
base 0 — rejected (ready bit never set)
base misaligned (+1) 0x0 ACCEPTED, then wedges

This validation layer is otherwise good: four distinct rejection codes, and the trusted region is explicitly excluded from the ring base.

The defect

hw/ring_unalign.py runs the aligned control first in the same boot — it succeeds, the heartbeat advances — and only then creates a ring at base + 1:

  aligned base (control)   create status=0x0 ACCEPTED   submit resp=0x0      hb_advancing=True
  base+0x1                 create status=0x0 ACCEPTED   submit resp=TIMEOUT  hb_advancing=False

The misaligned base is accepted at creation and the PSP then dies on the first submit. Because the control passed moments earlier in the same boot, this is not an inherited dead PSP — the failure mode that produced phantom hits twice in this audit.

Why it is a real inconsistency, not a policy choice

Alignment is enforced everywhere else in this interface:

  • cmd_buf misaligned ⇒ rejected 0x6 (even at +0x800),
  • TA image misaligned ⇒ rejected 0x34,
  • ring base inside the trusted region ⇒ rejected 0xa,
  • ring size bogus ⇒ rejected 0x4 / 0x5.

Only the ring base's alignment is unchecked, and the consequence is deferred to first use. This is the same shape as LOAD_TA with cmd_buf_len = 0 (accepted at load, hangs on first invoke): a parameter validated incompletely, with the failure surfacing later as a hang.

Not memory corruption

The PSP hangs; it does not write anywhere it should not. Recovery requires work/atx_power.py cycle 25; GPU/AM reset is insufficient.

Suggested fix

Check the ring base's alignment at creation and reject it with a status, as the size and the trusted-region overlap already are.