aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoruser <user@clank>2026-09-24 15:31:50 +0200
committeruser <user@clank>2026-09-24 15:31:50 +0200
commitb8cd95386daffcacd09eb9bdc031f87c52fc078c (patch)
treecae8eec23de29695ba16c9b78e771097db6c5a1b
parentRecord architectural insights from the AMD SP source (diff)
downloadamd-psp-re-b8cd95386daffcacd09eb9bdc031f87c52fc078c.tar.gz
amd-psp-re-b8cd95386daffcacd09eb9bdc031f87c52fc078c.tar.xz
amd-psp-re-b8cd95386daffcacd09eb9bdc031f87c52fc078c.zip
Downgrade Route C impact to provisional: the consumer scan has a blind spot
Asked how "only one consumer" was established, and the honest answer is that it was not. Recording the correction rather than defending the number. The scan saw only addresses appearing whole -- 32-bit literals and MOVW/MOVT immediates -- across two images. Register blocks are normally accessed as base + immediate offset, where the full address never appears in the image at all, so the detector is structurally blind to the exact access pattern this window's nature would predict. Tested for that rather than speculating. Scanning for values usable as a base with a 12-bit offset finds six candidates, one of which covers the entire window: sOS 0x021000 (covers the WHOLE window) at FA 0x168ca SYS_DRV 0x020d04, 0x020d1c, 0x020d5c, 0x020e30, 0x020f49 Trying to resolve the sOS candidate produced a region that does not decode as code at the offset the scan assumed, which further means the scan's address model for sOS is itself unverified. Two other weaknesses stated plainly: the control set was effectively N=1, since one of the two positive controls failed and its build-mismatch explanation is evidence-backed but post-hoc; and coverage was 2 images, excluding the boot ROM, earlier bootloader stages and every TA. So "firmware references 3 of 415 dwords" must be read as "3 whole-address references in 2 images, with 6 unresolved indexable bases and an unverified address model". The bounded-low impact rating rested on that count and is downgraded to provisional in the register. The capability itself is unaffected and remains confirmed on hardware.
-rw-r--r--psp_out/FINDING-ROUTEC-WINDOW-IDENTIFIED.md54
-rw-r--r--psp_out/VULN-AUDIT-WHAT-WE-ACTUALLY-HAVE.md2
2 files changed, 55 insertions, 1 deletions
diff --git a/psp_out/FINDING-ROUTEC-WINDOW-IDENTIFIED.md b/psp_out/FINDING-ROUTEC-WINDOW-IDENTIFIED.md
index 6888f4e..71abcad 100644
--- a/psp_out/FINDING-ROUTEC-WINDOW-IDENTIFIED.md
+++ b/psp_out/FINDING-ROUTEC-WINDOW-IDENTIFIED.md
@@ -105,3 +105,57 @@ real, impact bounded-low on the evidence available** — with the standing cavea
that consumers in hardware, or in code we do not hold, cannot be excluded by a
scan over the images we have. That caveat is why this is "bounded-low" and not
"none".
+
+---
+
+# CORRECTION: "3 of 415" is NOT established — the detector has a demonstrated blind spot
+
+Prompted by the question "how did you establish there's only one consumer?".
+Re-examining the method rather than the result, the answer is: **I did not
+establish it.**
+
+## What the scan could see
+
+Only addresses appearing *whole*: 32-bit literals in constant pools, and
+`MOVW`/`MOVT` immediate pairs. Over two images (sOS, SYS_DRV).
+
+## What it structurally cannot see
+
+Register blocks are normally accessed as **base + immediate offset**. A
+sequence holding `0x21000` in a register and doing `ldr r0, [r1, #0x500]` never
+materialises `0x21500` anywhere in the image, so the scan is blind to it — and
+that is the *expected* access pattern for the very thing this window looks like.
+
+Tested for it. Scanning the band `[window_lo - 0x1000, window_hi]` for values
+usable as a base with a 12-bit offset finds **six candidates**:
+
+ sOS base 0x021000 (covers the ENTIRE window) at FA 0x168ca
+ SYS_DRV base 0x020d04 at 0xE0EC5C
+ SYS_DRV base 0x020d1c at 0xE104B4, 0xE1657C
+ SYS_DRV base 0x020d5c at 0xE180F8
+ SYS_DRV base 0x020e30 at 0xE18288
+ SYS_DRV base 0x020f49 at 0xE01DEC
+
+An attempt to resolve the sOS one did not decode as code at the offset the scan
+assumed, which additionally means **the scan's address model for sOS is itself
+unverified**.
+
+## Further weaknesses, stated plainly
+
+* **The control set was effectively N=1.** Of two positive controls, `0x2161C`
+ failed; the build-mismatch explanation for it is evidence-backed but post-hoc.
+ A detector validated by one surviving control is thin — and this project's own
+ standing lesson is that a scan is worthless until it can find a known positive.
+* **Coverage was 2 images**, not the boot ROM, earlier bootloader stages, or any
+ TA.
+
+## Status of the impact rating
+
+"Firmware references 3 of 415 dwords" should be read as **"3 whole-address
+references in 2 images, with 6 unresolved indexable bases and an unverified
+address model"** — not as a census of consumers.
+
+The bounded-low rating rested on that count, so it is **downgraded to
+provisional** until either the six candidates are resolved or the scan is
+rebuilt to follow base+offset addressing. The capability itself is unaffected;
+it remains confirmed on hardware.
diff --git a/psp_out/VULN-AUDIT-WHAT-WE-ACTUALLY-HAVE.md b/psp_out/VULN-AUDIT-WHAT-WE-ACTUALLY-HAVE.md
index a2a5fb7..a18bdae 100644
--- a/psp_out/VULN-AUDIT-WHAT-WE-ACTUALLY-HAVE.md
+++ b/psp_out/VULN-AUDIT-WHAT-WE-ACTUALLY-HAVE.md
@@ -15,7 +15,7 @@ firmware under Unicorn · **[ST]** static/disassembly only.
| **ASD 0x308 OOB read** (`VULN-ASD-308-BYPASS` / `-REACHABLE`) | [HW] | Unauthenticated, no session, single `INVOKE_CMD` via HDCP cmd 0x12. Faults (DFSR 0x37, DFAR ~0xd5b000) -> **DoS**. Returns no data. |
| **HDCP TA stack overflow** (`VULN-HDCP-TA-STACK-OVERFLOW`) | [HW] | Reached and triggered from the host, no display needed. Canary-blocked -> **DoS**. |
| **HDCP session-state bypass** (`VULN-HDCP-SESSION-STATE-BYPASS`) | [HW] | Real logic bug; forges session state and defeats **one of two** gates on the overflow. The second gate holds. |
-| **LOAD_IP_FW unsigned register write** (`VULN-LOADIPFW-UNSIGNED-REGWRITE`) | [HW] | Genuinely unauthenticated, pre-signature, up to 64 attacker-chosen writes — but confined to `[0x21500,0x21B78]`. An exhaustive scan found **nothing reads those registers** — but note that scan covered only the images we hold, and the window has since been shown to be a **PSP-private address space** reached via `vawin_map_fixed`, not host SMN `0x21xxx` (a VCN reading was proposed and then **refuted on hardware**, `RERATE-ROUTEC-TARGET-MAY-BE-VCN.md`). The window is still **unidentified**, so the scan cannot be called exhaustive over the real consumers. Capability real, **impact bounded-low**. The window is now identified (`FINDING-ROUTEC-WINDOW-IDENTIFIED.md`): PSP-internal physical space reached via `vawin_map_fixed`, outside the two ranges `sos_check_va_window_request` protects (verified with controls). Of its 415 dwords, firmware we hold references **3** — and two are the handler's own fixup constants, leaving `0x215C0`, a boot-stage register used by the bootloader's `bl_main` before SYS_DRV runs. Consumers in hardware or in code we lack cannot be excluded, which is why this is bounded-low rather than none. |
+| **LOAD_IP_FW unsigned register write** (`VULN-LOADIPFW-UNSIGNED-REGWRITE`) | [HW] | Genuinely unauthenticated, pre-signature, up to 64 attacker-chosen writes — but confined to `[0x21500,0x21B78]`. An exhaustive scan found **nothing reads those registers** — but note that scan covered only the images we hold, and the window has since been shown to be a **PSP-private address space** reached via `vawin_map_fixed`, not host SMN `0x21xxx` (a VCN reading was proposed and then **refuted on hardware**, `RERATE-ROUTEC-TARGET-MAY-BE-VCN.md`). The window is still **unidentified**, so the scan cannot be called exhaustive over the real consumers. Capability real, **impact bounded-low**. The window is now identified (`FINDING-ROUTEC-WINDOW-IDENTIFIED.md`): PSP-internal physical space reached via `vawin_map_fixed`, outside the two ranges `sos_check_va_window_request` protects (verified with controls). **Impact rating PROVISIONAL** — the "3 of 415" scan has a demonstrated blind spot (it sees only whole addresses, not base+offset register access; 6 unresolved indexable bases found, one covering the whole window) and an effectively N=1 control set; see the CORRECTION section of `FINDING-ROUTEC-WINDOW-IDENTIFIED.md`. Of its 415 dwords, firmware we hold references **3** — and two are the handler's own fixup constants, leaving `0x215C0`, a boot-stage register used by the bootloader's `bl_main` before SYS_DRV runs. Consumers in hardware or in code we lack cannot be excluded, which is why this is bounded-low rather than none. |
| **TSU flash/update mailbox** (`FINDING-TSU-MAILBOX-HOST-REACHABLE`) | [HW] interface, [ST] chain | **A live, unauthenticated, host-reachable command interface into the flash/update subsystem.** MP0 `C2PMSG_115`/`116` + doorbell `73`; `tsu_mailbox_task` itself ORs `0x3C0` into the permission word, opening it to the host. Confirmed on silicon with real replies (`0x0B flash_info_get` -> `0x001560C8`, unknown ids -> `0x000A`). Commands 18-23 are gated on `byte_E25004`, which is **`0x00` in the shipped image, so they are not gated in practice** — including **23 `spi_set_bank_protect(0)`** (disable write protection) and **21 `bootrec_flush()`** (commit the boot record to flash). Implied chain 23 -> 19 -> 20 -> 21 would rewrite the **boot-priority record**, which selects the active image slot, **with no signature anywhere in the path**. **The chain was deliberately NOT executed** and is prohibited by `CONSTRAINTS.md`; it is a static hypothesis until tested with an external programmer attached. |
| **VCN unsigned register write** (`FINDING-VCN-GATE-OPENS-VIA-SMU-POWERUP`) | [HW] | `LOAD_IP_FW` type 49. Gate opened by `PPSMC_MSG_PowerUpVcn(0)`, an ordinary SMU mailbox message any driver can send — reproduced across three boots. Table ABI measured: only index 195 required, value `<= 0x100000`, everything else free, so **63 attacker-controlled `{u16 index, u32 value}` writes per call**, pre-signature, issued by the PSP via `SVC 0x7C` (PSP initiator identity). Parser proven to consume our entries (an out-of-bound value at index 195 rejects the call). **Writes never directly observed** — no validated read channel into VCN register space — so **impact open**, and it must be cited as "completes a register-write loop over attacker-controlled entries", NOT as "arbitrary VCN register write". |
| **TMR range rollback** (`VULN-CONFIRMED-TMR-RANGE-ROLLBACK`) | [HW] | Differential-confirmed across a firmware rollback. **DoS-class** — the file's own base sweep says "the corruption upside does NOT materialise". *Title corrected.* Also requires rolling back to <= 0.49.0.51. |