dc_create_stream_for_sink: unchecked NULL from dc_create_transfer_func() dereferenced in construct() -> kernel panic
Summary
construct() (dc_stream.c:58 static void so cannot report failure) calls dc_create_transfer_func() at dc_stream.c:107 which returns NULL on kzalloc GFP_KERNEL failure (dc_surface.c:195-208). Line 108 immediately derefs stream->out_transfer_func->type = TF_TYPE_BYPASS with NO NULL check -> kernel page fault on address 0. dc_create_stream_for_sink (140-157) calls construct(stream,sink) unconditionally at 152 then proceeds straight to kref_init+return; no error/rollback path. Sibling dc_sink_create (dc_sink.c:85-104) demonstrates correct pattern: construct returns bool checked with "if (false == construct(...)) goto construct_fail" + kfree. dc_stream deliberately diverged and lost failure handling. Attacker: local user with /dev/dri/cardN access; precondition GFP_KERNEL OOM during stream creation (memory pressure). Path: dc_create_stream_for_sink called from amdgpu_dm.c:2882 inside atomic-modeset stream-creation triggered by connector hotplug/DPMS/modeset/page-flip/DP-MST topology change. Impact: NULL-deref panic -> full system crash/DoS. No code execution (pure read of faulting pointer). AC:H (non-deterministic allocation failure under normal load; reliable in memory-constrained guest/cgroup). AV:L/AC:H/PR:L, A:H. Fix: construct returns bool; dc_create_stream_for_sink checks and calls destruct+kfree on failure (destruct already tolerates NULL out_transfer_func guarded at 114).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2038 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| VERDICT.md | verdict | Source-confirmation verdict for DF-2038 | 681 B | β raw |
| fix.diff | suggested-fix | NULL-check dc_create_transfer_func() result before deref | 390 B | view raw |
| ../fix_build.log | build-log | Batch kernel build log (all fixes, rc=0) | 5.6 MB | β download |
DF-2038 Verification Verdict
Severity: Medium Impact class: panic Verification method: Source-only confirmation (HW-gated, not triggerable on QEMU guest)
Verdict: REPRODUCED (source-confirmed)
The bug is confirmed in the audited source at the cited path:line. HW-gated: requires specific hardware/driver (not present in QEMU guest) - cannot trigger at runtime.
Fix: NULL-check dc_create_transfer_func() result before deref
Fix applied and validated in batch kernel build (rc=0, -Werror).
Fix validation
All 41-fix patches batched into single make -j6 nativekernel KERNCONF=X86_64_GENERIC build.
Build result: rc=0, 0 errors (full -Werror clean).
Fix verification
fixedVALIDATED: fix.diff applies cleanly + batch kernel build rc=0 -Werror; bug HW/module/runtime-gated, no runtime PoC re-test possible on guest.
VALIDATED: fix.diff applies cleanly + batch kernel build rc=0 -Werror; bug HW/module/runtime-gated, no runtime PoC re-test possible on guest.
Confirmed kernel references
β
Detail
Exploit chain
none
Evidence (decisive lines)
REPRODUCED (source-only): dc_stream construct() calls dc_create_transfer_func() which returns NULL on kzalloc GFP_KERNEL failure; line 108 immediately derefs the returned ptr. NULL deref panic.
Verified recommended fix
REPRODUCED (source-only): dc_stream construct() calls dc_create_transfer_func() which returns NULL on kzalloc GFP_KERNEL failure; line 108 immediately derefs the returned ptr. NULL deref panic.
Verdict
REPRODUCED (source-only): dc_stream construct() calls dc_create_transfer_func() which returns NULL on kzalloc GFP_KERNEL failure; line 108 immediately derefs the returned ptr. NULL deref panic.
No comments yet.