iceland_ih (Topaz): 5th and last unfiled instance of the unvalidated-wptr IH family β byte-identical to cz_ih.c in all vulnerable logic (permanent ithread spin on misaligned wptr + RB_OVERFLOW phase-import ring-end OOB read)
Summary
Discovered completing the family sweep: iceland_ih_get_wptr is byte-identical to cz_ih's (normalized diff; only register headers differ), CHIP_TOPAZ selected - same mask-only wptr return and phase-importing recovery. Pass-1 had marked this file clean before the family was identified. Cross-file filing (not in this batch's file rows - orchestrator re-buckets).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4902 Β· 7 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 1.7 KB | β raw | |
| VERDICT.md | β | 2.3 KB | β raw | |
| trigger_sketch.c | β | 1.5 KB | view raw | |
| fix.diff | β | 1.4 KB | view raw | |
| verdict.json | β | 2.9 KB | view raw | |
| manifest.json | β | 1.5 KB | view raw | |
| env.txt | β | 282 B | view raw |
DF-4902 β iceland_ih: unvalidated device-DMA'd IH wptr (DF-4843/DF-4854/DF-4887 5th twin)
File: sys/dev/drm/amd/amdgpu/iceland_ih.c (Topaz/Iceland discrete parts, selected at
vi.c:1600)
Iceland is the 5th 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 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], iceland_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 β iceland_ih.c is byte-identical to cz_ih.c in all vulnerable logic).
The two defects (identical shape to the filed twins)
- Permanent interrupt-thread spin β iceland_ih_get_wptr returns
wptr & ptr_maskonly (iceland_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(iceland_ih.c:202), importing the misaligned phase. For wptr' in [0xFFE4..0xFFEF]|OVERFLOW, rptr lands on [0xFFF4..0xFFFF] and the first decode (iceland_ih.c:253-256) reads up to 12 bytes past the exact-64KiB GTT ring BO (iceland_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-4902 VERDICT β iceland_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 iceland_ih (selected only for CHIP_TOPAZ at vi.c:1600), and the wptr source is device-side DMA into the host writeback slot (adev->wb.wb[adev->irq.ih.wptr_offs], iceland_ih.c:192, targeted by the writeback programmed at iceland_ih.c:133-138). Guest software cannot produce the trigger.
Why certain (code identity with filed twins)
- iceland_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): iceland_ih.c:207 returns
wptr & ptr_maskβ no 16-byte alignment check; the shared walker (amdgpu_ih.c:154-157) steps rptr by 16 (iceland_ih.c:266 decode; iceland_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): iceland_ih.c:202 parks rptr=(wptr+16)&0xFFFF with the wptr's misaligned phase; wptr' β [0xFFE4..0xFFEF]|OVERFLOW β rptr β [0xFFF4..0xFFFF] β first decode (iceland_ih.c:253-256) reads ring dwords [0x3FFD..0x4002] β up to 12 bytes past the exact-64KiB GTT ring BO allocated at iceland_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-4902, 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-4902/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 (iceland_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: byte-identical to cz_ih.c get_wptr/prescreen/decode); 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 iceland_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, iceland_ih.c:192). Code-certain by inspection: iceland_ih_get_wptr (iceland_ih.c:188-208) returns the device-DMA'd wptr masked only to the ring (iceland_ih.c:207) with no 16-byte alignment validation, and the RB_OVERFLOW recovery (iceland_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:1600/1692).
No comments yet.