Error path leaves half-initialized device on hive list and masks subsequent failures
Summary
amdgpu_xgmi_add_device adds device to hive->device_list at line 85 BEFORE attempting psp_xgmi_get_topology_info (line 89). If that call fails goto exit (95/114) without removing device so hive contains entry whose topology never fetched/set. On next add for another node stale entry device_id copied into tmp_topology (line 87) and psp_xgmi_set_topology_info driven across every node including half-baked one (line 99). ret only re-checked once (!ret at 109) so set_topology failure on later node still leaves earlier nodes state partially applied. Silent topology inconsistency across hive rather than clean failure. Amplifies UAF/leak issue DF-2204 by guaranteeing stale entries persist.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2205 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | readme | claim, source-trace pointers, fix summary | 2.9 KB | β raw |
| VERDICT.md | verdict | half-init error-path trace + amplification of DF-2204 + list_del fix | 3.2 KB | β raw |
| fix.diff | suggested-fix | list_del + INIT_LIST_HEAD on psp_xgmi_get_topology_info failure path | 948 B | view raw |
| build.sh | build-script | applies fix.diff + rebuilds amdgpu.ko in guest | 538 B | view raw |
| run.sh | run-script | HW-gated no-op runner | 404 B | view raw |
| build_baseline.log | build-log | unpatched amdgpu.ko build, rc=0, -Werror | 1.0 MB | β download |
| build_patched.log | build-log | patched amdgpu.ko rebuild, only amdgpu_xgmi.o recompiled, rc=0, -Werror | 12.6 KB | view raw |
| env.txt | environment | uname, cc, kern.version | 376 B | view raw |
DF-2205 β amdgpu_xgmi: error path leaves device half-initialized on hive list (Low)
Claim
amdgpu_xgmi_add_device() in
sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c list_add_tail()s the device into
hive->device_list (line 85) before attempting
psp_xgmi_get_topology_info() (line 89). If that call fails, the goto
exit at line 95 (and a second one at 114) does not remove the device,
so the hive permanently contains an entry whose topology was never fetched
or set. The next amdgpu_xgmi_add_device() for any other node then copies
that stale device_id into tmp_topology (line 87) and drives
psp_xgmi_set_topology_info across the half-baked node (line 99). ret
is only re-checked once (if (!ret) at line 109), so a
set_topology_info failure on a later node still leaves earlier nodes'
state partially applied.
Verification approach
HW-gated / source-only. Reachable only on Vega20 hardware with a PSP topology fetch that fails (faulty PSP firmware / bad hardware link). No GPU on this audit guest. Per the task brief, source-only confirmation is acceptable.
- Confirm the
list_add_tailprecedes thepsp_xgmi_get_topology_infocall. - Confirm the error-path
goto exitdoes not calllist_del. - Confirm the subsequent
list_for_each_entrywould re-enter the stale node. - Author
fix.diff(undo the linkage on error). - Phase 8 β apply all 5 batched fixes and rebuild
amdgpu.kowith-Werror.
Source trace (confirmed)
sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c:85βlist_add_tail(&adev->gmc.xgmi.head, &hive->device_list);sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c:89βret = psp_xgmi_get_topology_info(&adev->psp, count, tmp_topology);sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c:90-96βif (ret) { dev_err(...); goto exit; }β nolist_delbeforegoto.sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c:86-87β the next add for any node in the same hive will iteratehive->device_list(including the half-baked node) and copy its staledevice_idintotmp_topology.sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c:98-108βlist_for_each_entry(tmp_adev, &hive->device_list, ...)will drivepsp_xgmi_set_topology_infoacross every node, half-baked or not.sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c:109βif (!ret)re-checksretonly once; aset_topology_infofailure on a later node leaves earlier nodes' partial state in place.
Files
VERDICT.mdβ full narrative.fix.diffβ on thepsp_xgmi_get_topology_infofailure path,list_del(&adev->gmc.xgmi.head)+INIT_LIST_HEAD(...)before the existingdev_err/goto exit.build_baseline.logβ unpatchedamdgpu.kobuild, rc=0,-Werror.build_patched.logβ patchedamdgpu.korebuild (onlyamdgpu_xgmi.orecompiled), rc=0,-Werror.env.txtβ guest environment.
Reproduce
./build.sh # applies fix.diff + rebuilds amdgpu.ko ./run.sh # HW-gated no-op (see VERDICT.md)
DF-2205 β VERDICT
Verdict: REPRODUCED (source-only, HW-gated).
Class: silent state inconsistency / partial-init β topology corruption.
Mechanism
amdgpu_xgmi_add_device() (sys/dev/drm/amd/amdgpu/amdgpu_xgmi.c) links
the device into its hive before the topology-fetch step has been
validated:
/* amdgpu_xgmi.c:85 */
list_add_tail(&adev->gmc.xgmi.head, &hive->device_list);
list_for_each_entry(entry, &hive->device_list, head)
tmp_topology[count++].device_id = entry->device_id;
/* amdgpu_xgmi.c:89 */
ret = psp_xgmi_get_topology_info(&adev->psp, count, tmp_topology);
if (ret) {
dev_err(...);
goto exit; /* <-- list_del missing here */
}
If psp_xgmi_get_topology_info() fails, the function logs an error and
jumps to exit (mutex_unlock + return ret) without removing the
device from hive->device_list. The hive now permanently contains an
entry whose topology was never fetched or set.
The next amdgpu_xgmi_add_device() for any other device in the same hive:
- Iterates
hive->device_listat line 86 and copies the stale node'sdevice_idintotmp_topologyat line 87. - Drives
psp_xgmi_set_topology_infoacross every node β including the half-baked one β at line 99.
Worse, ret from psp_xgmi_set_topology_info is only re-checked once
(if (!ret) at line 109). If set_topology_info fails on a later
node, the loop breaks but earlier nodes' partial state remains applied
β the function returns the failure but the hive is left in a silently
inconsistent state.
This defect amplifies DF-2204: combined with the missing removal path, half-baked entries never get cleaned up, so the inconsistency is permanent for the lifetime of the hive (and across driver reloads).
Trigger surface / reachability
psp_xgmi_get_topology_info() fails when the PSP firmware is faulty, the
XGMI link is unhealthy, or the GPU is in an error state during probe.
Vega20-only (the function early-returns for older ASICs and APUs). On
this audit guest there is no GPU, so the partial-init cannot be exercised
live; the bug is confirmed at the source level and the fix compiles
cleanly (Phase 8).
Fix
fix.diff adds the missing cleanup on the error path:
ret = psp_xgmi_get_topology_info(&adev->psp, count, tmp_topology);
if (ret) {
list_del(&adev->gmc.xgmi.head);
INIT_LIST_HEAD(&adev->gmc.xgmi.head);
dev_err(...);
goto exit;
}
list_del + INIT_LIST_HEAD is the standard pattern: unlink from the
hive, then mark the node empty so a later amdgpu_xgmi_remove_device
(DF-2204's fix) and the idempotency guard both see it as unlinked. This
prevents the half-baked node from being visible to subsequent adds and
breaks the inconsistency amplification.
Phase 8 build validation
Applied fix.diff (plus the four other batched DRM fixes) to the in-guest
/usr/src, rebuilt amdgpu.ko with -Werror:
* baseline (unpatched) amdgpu.ko: rc=0 (build_baseline.log).
* patched amdgpu.ko: rc=0, only amdgpu_xgmi.o recompiled
(build_patched.log); no warnings, no errors.
Verdict
REPRODUCED at source level (HW-gated; no live repro possible on guest).
The missing cleanup on the topology-fetch error path is unambiguous from
the source; the fix compiles cleanly under -Werror.
Fix verification
fixedamdgpu.ko baseline+patched rc=0 -Werror
amdgpu.ko baseline+patched rc=0 -Werror
Confirmed kernel references
β
Detail
Exploit chain
none (HW-gated)
Evidence (decisive lines)
HW-gated. Source-confirmed: psp_xgmi_get_topology_info failure path doesn't list_del -> stale half-baked entry.
Verified recommended fix
HW-gated. Source-confirmed: psp_xgmi_get_topology_info failure path doesn't list_del -> stale half-baked entry.
Verdict
HW-gated. Source-confirmed: psp_xgmi_get_topology_info failure path doesn't list_del -> stale half-baked entry.
No comments yet.