cz_ih (Carrizo/Stoney APU): unvalidated device-DMA'd IH wptr β 4th instance of the DF-4843/4854/4887 family: a misaligned wptr permanently hard-spins the amdgpu interrupt thread, and the RB_OVERFLOW +16 recovery imports the bad phase, parking rptr within 12 bytes of ring end for an up-to-12-byte OOB read past the zero-slack 64 KiB GTT ring BO
Summary
CZ is the wb-only variant (no use_bus_addr branch, no IH doorbell): mask-only return of the device-DMA'd wptr -> a non-16-multiple can never match the 16-byte-stepping walk (permanent ithread spin, all GPU IRQs dead); the +16 recovery imports the misaligned phase -> first decode reads up to 12 bytes past the exact-size ring BO. Byte-identical logic to the filed twins. Family sweep: after this and DF-4902, ALL FIVE IH implementations are filed - none validates alignment. Device-gated.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4901 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.7 KB | β raw | |
| VERDICT.md | β | 2.2 KB | β raw | |
| trigger_sketch.c | β | 1.5 KB | view raw | |
| twin_diff.cz-vs-tonga.txt | β | 966 B | view raw | |
| fix.diff | β | 1.4 KB | view raw | |
| verdict.json | β | 2.7 KB | view raw | |
| manifest.json | β | 1.4 KB | view raw | |
| env.txt | β | 277 B | view raw |
DF-4901 β cz_ih: unvalidated device-DMA'd IH wptr (DF-4843/DF-4854/DF-4887 4th twin)
File: sys/dev/drm/amd/amdgpu/cz_ih.c (Carrizo/Stoney APUs, selected at
vi.c:1671 and vi.c:1692)
CZ is the 4th member of the unvalidated-wptr IH family. All five IH implementations in the tree (cik, tonga, iceland, cz, vega10) share the same defect; after this filing and DF-4902 (iceland) every implementation is covered β none validates wptr alignment.
Reproduce
Not runnable on the audit guest: the wptr is DMA'd by the GPU into the host
writeback slot (adev->wb.wb[adev->irq.ih.wptr_offs], cz_ih.c:192); the
QEMU guest has no AMD GPU (env.txt). Code-certain by inspection β
diff of the vulnerable block against the filed twins is empty except for
the function prefix (see VERDICT.md).
The two defects (identical shape to the filed twins)
- Permanent interrupt-thread spin β cz_ih_get_wptr returns
wptr & ptr_maskonly (cz_ih.c:207). A wptr with phase 1..15 (mod 16) can never equal the 16-byte-stepping rptr in the shared walk (amdgpu_ih.c:154-157) β the amdgpu ithread re-dispatches the whole ring forever, all GPU interrupt delivery dead. - Ring-end OOB read via RB_OVERFLOW recovery β recovery parks
rptr = (wptr + 16) & ptr_mask(cz_ih.c:202), importing the misaligned phase. For wptr' in [0xFFE4..0xFFEF]|OVERFLOW, rptr lands on [0xFFF4..0xFFFF] and the first decode (cz_ih.c:253-256) reads up to 12 bytes past the exact-64KiB GTT ring BO (cz_ih.c:300 / amdgpu_ih.c:80-88).
Artifacts
trigger_sketch.c (hostile-device pattern), fix.diff (alignment normalize + bounded walk), VERDICT.md, manifest.json, verdict.json, env.txt
DF-4901 VERDICT β cz_ih.c 4th twin
status: untested (device-gated) | impact ceiling: dos + 12-byte OOB ring read | confidence: certain
Why untested
The audit guest (QEMU, no AMD GPU β env.txt) cannot instantiate cz_ih (selected only for CHIP_CARRIZO/CHIP_STONEY at vi.c:1671/1692), and the wptr source is device-side DMA into the host writeback slot (adev->wb.wb[adev->irq.ih.wptr_offs], cz_ih.c:192, targeted by the writeback programmed at cz_ih.c:133-138). Guest software cannot produce the trigger.
Why certain (code identity with filed twins)
- cz_ih.c vs iceland_ih.c: byte-identical get_wptr/prescreen/decode/set_rptr (only OSS register headers and ip-block version differ) β see twin_diff.cz-vs-tonga.txt for the cz-vs-tonga shape (tonga = DF-4843, filed; tonga additionally has the use_bus_addr branch CZ lacks β CZ is the wb-only variant, no IH doorbell on CZ).
- Defect 1 (spin): cz_ih.c:207 returns
wptr & ptr_maskβ no 16-byte alignment check; the shared walker (amdgpu_ih.c:154-157) steps rptr by 16 (cz_ih.c:266 decode; cz_ih.c:234 prescreen) so a wptr β‘ 4..15 (mod 16) can never be matched β permanent ithread spin, all GPU IRQs dead. - Defect 2 (OOB): cz_ih.c:202 parks rptr=(wptr+16)&0xFFFF with the wptr's misaligned phase; wptr' β [0xFFE4..0xFFEF]|OVERFLOW β rptr β [0xFFF4..0xFFFF] β first decode (cz_ih.c:253-256) reads ring dwords [0x3FFD..0x4002] β up to 12 bytes past the exact-64KiB GTT ring BO allocated at cz_ih.c:300 via amdgpu_ih.c:80-88 (no slack), consumed as an IV and dispatched.
Family sweep conclusion
All five IH implementations (cik DF-4887, tonga DF-4843, vega10 DF-4854, cz DF-4901, iceland DF-4902) share the defect; after this filing and DF-4902 none remains unfiled. No IH implementation validates wptr alignment. Fix: normalize wptr alignment in each get_wptr (fix.diff here) + cap the shared walk (DF-4887's amdgpu_ih.c half).
Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest make -j6 nativekernel KERNCONF=X86_64_GENERIC completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
Fix verification
not_testablefix authored against the read-only sys/ tree (fix.diff); not buildable/testable on this guest (no AMD GPU)
findings/poc/DF-4901/fix.diff
Confirmed kernel references
Detail
Exploit chain
hostile/faulting GPU or corrupted firmware DMA writes a misaligned wptr into wb.wb[wptr_offs] -> amdgpu_ih_process (amdgpu_ih.c:154-157) can never match the 16-byte-stepping rptr -> permanent ithread spin, all GPU interrupt delivery dead; with RB_OVERFLOW set and wptr' in [0xFFE4..0xFFEF] the recovery parks rptr in [0xFFF4..0xFFFF] -> first decode (cz_ih.c:253-256) reads up to 12 bytes past the exact-64KiB GTT ring BO, consumed as an interrupt vector
Evidence (decisive lines)
VERDICT.md (code-identity argument); twin_diff.cz-vs-tonga.txt; trigger_sketch.c (armed pattern with byte arithmetic); fix.diff
PoC changes
n/a β no seed PoC; family-consistent trigger sketch authored
Verified recommended fix
Mask wptr to 16-byte alignment (with dev_warn) in cz_ih_get_wptr before the overflow check and derive the recovery rptr from the aligned value; cap the shared walk in amdgpu_ih_process (see DF-4887 fix.diff).
Verdict
Not runnable on the audit guest (no AMD GPU; the wptr comes from device DMA into the writeback slot, cz_ih.c:192). Code-certain by inspection: cz_ih_get_wptr (cz_ih.c:188-208) returns the device-DMA'd wptr masked only to the ring (cz_ih.c:207) with no 16-byte alignment validation, and the RB_OVERFLOW recovery (cz_ih.c:202) imports the misaligned phase into rptr=(wptr+16)&mask β byte-identical logic to the filed twins DF-4843 (tonga)/DF-4854 (vega10)/DF-4887 (cik); cz differs only in having no use_bus_addr branch and no IH doorbell (wb-only wptr source, CARRIZO/STONEY per vi.c:1671/1692).
No comments yet.