aboutsummaryrefslogtreecommitdiffstats
path: root/hw
diff options
context:
space:
mode:
authoruser <user@clank>2026-10-07 23:37:44 +0200
committeruser <user@clank>2026-10-07 23:37:44 +0200
commitd22d24d473fae8a2cecff5e320755fe235689968 (patch)
tree3abcb44d7a4708b13c877671522f6b8654b5c80a /hw
parent[HW] isolated per-slot writes refute the saved-LR route: Addendum B closed as... (diff)
downloadamd-psp-re-d22d24d473fae8a2cecff5e320755fe235689968.tar.gz
amd-psp-re-d22d24d473fae8a2cecff5e320755fe235689968.tar.xz
amd-psp-re-d22d24d473fae8a2cecff5e320755fe235689968.zip
RETRACT Addenda C/D: it was a hit. One-invoke arbitrary chosen PC, confirmed on silicon
Addenda C and D declared the saved-LR route a negative. Wrong, and the error was mine in decoding the fault frame rather than in the experiment. I assumed faultFrame[0] was the faulting PC; on 22.0.0.77 word0 = 0x4055d8 is a build-specific constant, which Add.6 of the FE09 document states outright. The real discriminator is word3 (FSR) plus word4 (address), and the hijack report already documents the decode. Re-read that way, every row I labelled 'deref: painted a pointer reg' was a control-flow redirect. Calibration at slot 0x41bfbc settles it against two independent prior measurements: PC_VAL=0x00400000 -> FSR=0x80f (write perm, WnR) addr=0x0, which is Add.92's 17 ARM NOPs from 0x400000 reaching the store at 0x400044, with addr=0 because r4/r8 are zero (Add.95). So execution PROCEEDED from the planted PC. PC_VAL=0x00416e60 -> FSR=0xf addr=0x416e60, the report's own XN-on-fetch signature for .bss. The earlier 0xDEADBEE0 rows read the same way: FS=0x5 translation at the unmapped planted PC. So the geometry is measured, not predicted: SP0=0x41c000, SP_e(0x404c74)=0x41bfc0, lr at 0x41bfbc, which matches the analytic chain SP0 -0x10 -0x10 -0x20 exactly. Addendum B's method was right and only its SP0 anchor was off, because the UNLOAD path it was derived from carries tlApiFree's ~0x40-byte request block. Net: a single FE0A selector-4 invoke sets PC to any 32-bit value, no carve, no lottery, no wedge, since control leaves before the parent's unclamped copy. The pop also restores r4..sl from slots inside the write's reach, and each invoke carries two independently aimed 8-byte writes with independently chosen contents, so sl and PC can be set together. This breaks section 4 claim 1 of the hijack report outright. Process note recorded: three runs produced the hit signature before I recognised it, and I wrote two negative addenda on top of it. I validated the write with an in-buffer positive control but never validated the fault-frame decoder against a known reference, which is precisely the project rule I had been applying everywhere else.
Diffstat (limited to 'hw')
-rw-r--r--hw/drive_calib.sh16
1 files changed, 16 insertions, 0 deletions
diff --git a/hw/drive_calib.sh b/hw/drive_calib.sh
new file mode 100644
index 0000000..f3e43f6
--- /dev/null
+++ b/hw/drive_calib.sh
@@ -0,0 +1,16 @@
+#!/bin/bash
+# Decisive calibration at the candidate LR slot 0x41bfbc.
+# PC_VAL=0x00400000 is MAPPED R-X and even (ARM). Add.92: planting it executes 17 ARM
+# NOPs and faults at 0x400044. So:
+# addr == 0x400044 (or anything != PC_VAL) -> execution PROCEEDED from our PC = PC CONTROL
+# addr == 0x400000 with FSR 0x5/0xf -> we only reached the fetch
+# the usual 0x4064000 / FSR 0x857 -> no redirect at all (parent copy)
+echo "START $(date +%T)"
+for PV in 0x00400000 0x00416e60; do
+ cd /root/psp && source ./env.sh >/dev/null 2>&1
+ rm -f /tmp/am_usb*.lock
+ $PSP_PY work/atx_power.py cycle 18 >/dev/null 2>&1
+ cd /root/psp/hw
+ SLOT=0x41bfbc PC_VAL=$PV timeout 150 $PSP_PY /root/psp/hw/gcp_slot_shot.py 2>&1 | sed "s/^/PC_VAL=$PV /" | grep -E "SLOT=|Traceback" | head -2
+done
+echo CALIB-DONE