BUG_ON kernel panic in atomic_check via MST connector without dc_sink
Summary
dm_update_crtcs_state at amdgpu_dm.c:5290 adds MST skip (goto next_crtc) when !dc_sink&&mst_port. At :5333 next_crtc label guard does NOT check stream!=NULL. At :5344 unconditional BUG_ON(dm_new_crtc_state->stream==NULL) fires because MST skip skipped stream assignment at :5305. Local user with /dev/dri/card0 issues DRM_IOCTL_MODE_ATOMIC with enable+active on CRTC bound to MST child with dc_sink==NULL (hot-unplugged downstream). Reliable kernel panic. Fix: add stream!=NULL to guard or remove BUG_ON.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-1152 Β· 8 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | Full source trace + reachability analysis | 3.9 KB | β raw |
| fix.diff | suggested-fix | Strengthen guard at L5333 to also require stream!=NULL (git apply-able, validated) | 509 B | view raw |
| build.sh | build-doc | Documents why no executable PoC is possible | 337 B | view raw |
| run.sh | run-doc | Documents why runtime trigger is impossible on this guest | 176 B | view raw |
| env.txt | environment | uname + kernel symbol inventory proving amdgpu absent + no /dev/dri | 395 B | view raw |
| README.md | readme | human reproduce doc | 749 B | β raw |
| ../fix_build_combined.log | build-log | Combined 41-finding kernel build (rc=0, -Werror clean) | 5.6 MB | β download |
| ../fix_build_summary.txt | build-summary | Summary of the combined 41-finding kernel build | 826 B | view raw |
DF-1152 β BUG_ON kernel panic in amdgpu_dm dm_update_crtcs_state
Result
NOT REPRODUCED on this guest. Real source-level defense-in-depth bug;
fix authored. See VERDICT.md for the full analysis.
Build & run
./build.sh # documents why no executable PoC is possible ./run.sh # documents why runtime trigger is impossible
Reachability summary
- amdgpu_dm is part of amdgpu, not in
X86_64_GENERIC(0 symbols) - No AMD GPU on the QEMU guest, no
/dev/dri - Trigger needs MST hot-unplug + DRM atomic ioctl on AMD hardware
Fix
fix.diff β strengthen guard at
sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5333 to also require
dm_new_crtc_state->stream != NULL. Applies cleanly with git apply.
DF-1152 β BUG_ON kernel panic in dm_update_crtcs_state via MST connector
Verdict
NOT REPRODUCED on this guest (defense-in-depth source bug confirmed; path unreachable on the default GENERIC DragonFlyBSD kernel running in QEMU). Real source-level defect; fix.diff authored.
Mechanism (source trace, bug confirmed real)
In sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c, dm_update_crtcs_state()
runs the CRTC update logic in two passes β first with enable=false
(disables), then with enable=true (enables), called from
amdgpu_dm_atomic_check() (:5688 and :5694).
When called with enable=true, the per-CRTC body has this flow:
/* sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5284-5291 */
} else { /* Add stream for any updated/enabled CRTC */
...
/* L5290 */ if (!aconnector || (!aconnector->dc_sink && aconnector->mst_port))
/* L5291 */ goto next_crtc;
...
/* L5305 */ dm_new_crtc_state->stream = new_stream; /* ONLY inside modeset_required */
The MST "quick fix" at L5290 jumps past the only stream assignment at L5305.
Then at the next_crtc: label:
/* sys/dev/drm/amd/display/amdgpu_dm/amdgpu_dm.c:5324-5344 */
next_crtc:
/* L5326 */ if (new_stream) dc_stream_release(new_stream);
...
/* L5333 */ if (!(enable && aconnector && new_crtc_state->enable &&
/* L5334 */ new_crtc_state->active))
/* L5335 */ continue;
...
/* L5344 */ BUG_ON(dm_new_crtc_state->stream == NULL); /* UNCONDITIONAL */
The guard at L5333 checks enable && aconnector && crtc_enable && active
but does NOT check dm_new_crtc_state->stream != NULL. So the path:
- Unprivileged local user opens
/dev/dri/card0(amdgpu render node), - Issues
DRM_IOCTL_MODE_ATOMICrequesting enable+active on a CRTC that is bound to a now-hot-unplugged MST downstream port (soaconnectoris non-NULL butdc_sink == NULLandmst_port == true), dm_update_crtcs_state(enable=true)skips stream assignment at L5290 (MST goto), but the L5333 guard passes (enable/active/connector all OK),- L5344
BUG_ON(stream == NULL)fires β kernel panic.
This is a real logic bug β the guard at L5333 must also require
dm_new_crtc_state->stream != NULL, or the BUG_ON must be replaced with
continue/graceful failure. (The kernel's BUG_ON expands to panic()
on DragonFly/linuxdrm.)
Why it does NOT reproduce on this guest
- amdgpu_dm is part of the amdgpu driver which is not in GENERIC.
grep -E 'radeon|amdgpu' sys/config/X86_64_GENERICis empty;nm /boot/kernel/kernel.debug | grep -ciE 'radeon|amdgpu'β 0. The amdgpu.ko loadable module exists but is not loaded on this guest (kldstat | grep amdgpuempty). - No AMD GPU in the QEMU guest. Even with the module loaded there is
no Display Core (DC) on the virtual PCI bus, so
aconnector/dc_sinknever exist and the DRM atomic ioctl has no amdgpu CRTC to act on. - Threat model is local user with GPU + MST hub. The trigger requires AMD hardware with DisplayCore (e.g. Raven Ridge / Navi / newer APU or dGPU), a daisy-chained MST hub, a hot-unplug event on the downstream port, and then the atomic modeset request β none of which exist in this serial-console QEMU VM.
Exploit chain
none β primitive (kernel panic via BUG_ON) requires AMD GPU + MST topology + module load + DRM atomic ioctl, none of which are present on this guest.
PoC changes
none β no executable PoC is possible; the path is dead code in the running kernel and requires AMD hardware that the QEMU VM does not have.
Recommended fix
Replace the unconditional BUG_ON(...) at L5344 with a graceful continue
when stream == NULL, AND/OR strengthen the guard at L5333 to also require
dm_new_crtc_state->stream != NULL. See fix.diff β applies cleanly
with git apply (validated). Matches the finding markdown's proposal.
Fix verification
not_testablegit apply --check validated
see evidence pack
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
β
Verdict
Source-confirmed. amdgpu_dm BUG_ON on NULL stream via MST hot-unplug. amdgpu not in GENERIC.
No comments yet.